1 /*
2 * Copyright 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package com.android.photopicker.tests.utils.mockito
18
19 import android.content.Context
20 import org.mockito.ArgumentCaptor
21 import org.mockito.ArgumentMatchers
22 import org.mockito.Mockito
23 import org.mockito.invocation.InvocationOnMock
24
25 /**
26 * Wrapper around Mockito's when method. "when" is a protected keyword in Kotlin, so this provides a
27 * convenient wrapper to use.
28 */
whenevernull29 fun <Type> whenever(mock: Type) = Mockito.`when`(mock)
30
31 /**
32 * Wrapper around Mockito's when method. "when" is a protected keyword in Kotlin, so this provides a
33 * convenient wrapper to use that also includes a block for creating a .thenAnswer chained call.
34 */
35 fun <Type> whenever(mock: Type, block: InvocationOnMock.() -> Type) =
36 Mockito.`when`(mock).thenAnswer { block(it) }
37
38 /**
39 * Returns ArgumentCaptor.capture() as nullable type to avoid [java.lang.IllegalStateException] when
40 * null is returned.
41 *
42 * Generic T is nullable because implicitly bounded by Any?.
43 */
capturenull44 fun <Type> capture(argumentCaptor: ArgumentCaptor<Type>): Type = argumentCaptor.capture()
45
46 /**
47 * Registers mock returns for the designated system service. This is a Mockito helper to help with
48 * the [requireSystemService] extension for correctly mocking out services based on their type
49 * signatures.
50 *
51 * @param context The (mock) context object to stub out service on.
52 * @param classToMock The java class of the system service to be mocked.
53 * @param block A block that returns the mocked service value.
54 */
55 fun <Type> mockSystemService(
56 context: Context,
57 classToMock: Class<Type>,
58 block: InvocationOnMock.() -> Type
59 ) {
60 whenever(context.getSystemServiceName(classToMock)) { classToMock.simpleName }
61 whenever(context.getSystemService(classToMock.simpleName)) { block() }
62 }
63
64 /**
65 * We can't use [org.mockito.ArgumentMatchers.eq] method directly for non-nullable Kotlin objects.
66 * This utility method checks for nullability of the result [org.mockito.ArgumentMatchers.eq] and
67 * returns the same value if found to be null.
68 *
69 * @param value The value that you wish to pass to eq
70 */
nonNullableEqnull71 fun <Type> nonNullableEq(value: Type): Type {
72 return ArgumentMatchers.eq(value) ?: value
73 }
74
75 /**
76 * We can't use [org.mockito.ArgumentMatchers.any] method directly for non-nullable Kotlin objects.
77 * This utility method checks for nullability of the result [org.mockito.ArgumentMatchers.eq] and
78 * returns the same value if found to be null.
79 *
80 * @param typeClass The java class of the type that should match [org.mockito.ArgumentMatchers.any]
81 * @param defaultValue a non-null instance of the type [typeClass]
82 */
nonNullableAnynull83 fun <Type> nonNullableAny(typeClass: Class<Type>, defaultValue: Type): Type {
84 return ArgumentMatchers.any(typeClass) ?: defaultValue
85 }
86