Skip to content

Commit bbe3afa

Browse files
Ian BirdIanDBird
authored andcommitted
Migrate Unit Tests to MockK
1 parent bccd391 commit bbe3afa

File tree

8 files changed

+135
-157
lines changed

8 files changed

+135
-157
lines changed

gradle/libs.versions.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[versions]
2-
agp = "8.4.1"
2+
agp = "8.4.2"
33
kotlin = "2.0.0"
44
core-ktx = "1.13.1"
55
junit = "4.13.2"
@@ -10,6 +10,7 @@ compose-bom = "2024.05.00"
1010
compose-tooling = "1.6.7"
1111
gma = "23.1.0"
1212
ima = "3.33.0"
13+
mockkVersion = "1.13.11"
1314

1415
[libraries]
1516
core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "core-ktx" }
@@ -41,8 +42,8 @@ androidx-activity-ktx = { group = "androidx.activity", name = "activity-ktx", ve
4142
junit = { group = "junit", name = "junit", version.ref = "junit" }
4243
kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "coroutines-version" }
4344
json = { group = "org.json", name = "json", version = "20240303" }
44-
mockito-kotlin = { group = "org.mockito.kotlin", name = "mockito-kotlin", version = "4.1.0" }
45-
mockito-inline = { group = "org.mockito", name = "mockito-inline", version = "4.8.0" }
45+
mockk-android = { group = "io.mockk", name = "mockk-android", version.ref = "mockkVersion" }
46+
mockk-agent = { group = "io.mockk", name = "mockk-agent", version.ref = "mockkVersion" }
4647

4748
[plugins]
4849
androidApplication = { id = "com.android.application", version.ref = "agp" }

sdk/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ android {
3535
dependencies {
3636
testImplementation(libs.junit)
3737

38-
testImplementation(libs.mockito.kotlin)
39-
testImplementation(libs.mockito.inline)
38+
testImplementation(libs.mockk.android)
39+
testImplementation(libs.mockk.agent)
4040

4141
testImplementation(libs.json)
4242
}

sdk/src/test/java/com/uid2/UID2ClientTest.kt

Lines changed: 48 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ import com.uid2.network.NetworkSession
1111
import com.uid2.utils.KeyUtils
1212
import com.uid2.utils.Logger
1313
import com.uid2.utils.TimeUtils
14+
import io.mockk.every
15+
import io.mockk.junit4.MockKRule
16+
import io.mockk.mockk
1417
import kotlinx.coroutines.runBlocking
1518
import kotlinx.coroutines.test.StandardTestDispatcher
1619
import kotlinx.coroutines.test.TestDispatcher
@@ -22,33 +25,31 @@ import org.junit.Assert.assertNull
2225
import org.junit.Assert.assertThrows
2326
import org.junit.Assert.assertTrue
2427
import org.junit.Before
28+
import org.junit.Rule
2529
import org.junit.Test
26-
import org.junit.runner.RunWith
27-
import org.mockito.junit.MockitoJUnitRunner
28-
import org.mockito.kotlin.any
29-
import org.mockito.kotlin.anyOrNull
30-
import org.mockito.kotlin.mock
31-
import org.mockito.kotlin.whenever
3230
import java.security.KeyPair
3331
import java.security.PublicKey
32+
import javax.crypto.SecretKey
3433

35-
@RunWith(MockitoJUnitRunner::class)
3634
class UID2ClientTest {
35+
@get:Rule
36+
val mockkRule = MockKRule(this)
37+
3738
private val testDispatcher: TestDispatcher = StandardTestDispatcher()
3839

39-
private val networkSession: NetworkSession = mock()
40+
private val networkSession = mockk<NetworkSession>()
4041
private val packageName = "com.uid2.devapp"
41-
private val dataEnvelope: DataEnvelope = mock()
42-
private val keyUtils: KeyUtils = mock()
43-
private val timeUtils: TimeUtils = mock()
44-
private val logger: Logger = mock()
42+
private val dataEnvelope = mockk<DataEnvelope>(relaxed = true)
43+
private val keyUtils = mockk<KeyUtils>()
44+
private val timeUtils = mockk<TimeUtils>()
45+
private val logger = mockk<Logger>(relaxed = true)
4546

4647
private val url = "https://test.dev"
4748
private val refreshToken = "RefreshToken"
4849
private val refreshKey = "RefreshKey"
4950

50-
private val keyPair: KeyPair = mock()
51-
private val keyPairPublic: PublicKey = mock()
51+
private val keyPair = mockk<KeyPair>()
52+
private val keyPairPublic = mockk<PublicKey>()
5253
private val keyPairPublicEncoded = ByteArray(12)
5354

5455
private val SUBSCRIPTION_ID = "subscription_id"
@@ -57,20 +58,22 @@ class UID2ClientTest {
5758
@Before
5859
fun before() {
5960
// By default, don't encrypt the data. Just convert it directly to a ByteArray.
60-
whenever(dataEnvelope.encrypt(any(), any(), any(), any())).thenAnswer {
61-
return@thenAnswer (it.arguments[1] as String).toByteArray()
61+
every { dataEnvelope.encrypt(any(), any(), any(), any()) }.answers {
62+
(secondArg() as String).toByteArray()
6263
}
6364

64-
whenever(keyUtils.generateServerPublicKey(any())).thenReturn(mock())
65-
whenever(keyUtils.generateKeyPair()).thenReturn(keyPair)
66-
whenever(keyUtils.generateSharedSecret(any(), any())).thenReturn(mock())
67-
whenever(keyUtils.generateIv(any())).thenAnswer { ByteArray(it.arguments[0] as Int) }
68-
whenever(keyUtils.generateAad(any(), any())).thenReturn("")
65+
every { dataEnvelope.decrypt(any<String>(), any<String>(), any<Boolean>()) }.returns(null)
66+
67+
every { keyUtils.generateServerPublicKey(any()) }.returns(mockk<PublicKey>())
68+
every { keyUtils.generateKeyPair() }.returns(keyPair)
69+
every { keyUtils.generateSharedSecret(any(), any()) }.returns(mockk<SecretKey>(relaxed = true))
70+
every { keyUtils.generateIv(any()) }.answers { ByteArray(firstArg() as Int) }
71+
every { keyUtils.generateAad(any(), any()) }.returns("")
6972

70-
whenever(keyPairPublic.encoded).thenReturn(keyPairPublicEncoded)
71-
whenever(keyPair.public).thenReturn(keyPairPublic)
73+
every { keyPairPublic.encoded }.returns(keyPairPublicEncoded)
74+
every { keyPair.public }.returns(keyPairPublic)
7275

73-
whenever(timeUtils.now()).thenReturn(0)
76+
every { timeUtils.now() }.returns(0)
7477
}
7578

7679
//region generateIdentity
@@ -91,7 +94,7 @@ class UID2ClientTest {
9194
val client = withClient()
9295

9396
// Mock the KeyUtils to fail to generate the required PublicKey.
94-
whenever(keyUtils.generateServerPublicKey(any())).thenReturn(null)
97+
every { keyUtils.generateServerPublicKey(any()) }.returns(null)
9598

9699
// Verify the expected CryptoException is thrown.
97100
assertThrows(CryptoException::class.java) {
@@ -110,7 +113,7 @@ class UID2ClientTest {
110113
val client = withClient()
111114

112115
// Mock the KeyUtils to fail to generate the required KeyPair.
113-
whenever(keyUtils.generateKeyPair()).thenReturn(null)
116+
every { keyUtils.generateKeyPair() }.returns(null)
114117

115118
// Verify the expected CryptoException is thrown.
116119
assertThrows(CryptoException::class.java) {
@@ -129,7 +132,7 @@ class UID2ClientTest {
129132
val client = withClient()
130133

131134
// Mock the KeyUtils to fail to generate the required SharedSecret.
132-
whenever(keyUtils.generateSharedSecret(any(), any())).thenReturn(null)
135+
every { keyUtils.generateSharedSecret(any(), any()) }.returns(null)
133136

134137
// Verify the expected CryptoException is thrown.
135138
assertThrows(CryptoException::class.java) {
@@ -148,7 +151,7 @@ class UID2ClientTest {
148151
val client = withClient()
149152

150153
// Mock the DataEnvelope to fail to encrypt the given payload.
151-
whenever(dataEnvelope.encrypt(any(), any(), any(), any())).thenReturn(null)
154+
every { dataEnvelope.encrypt(any(), any(), any(), any()) }.returns(null)
152155

153156
// Verify the expected CryptoException is thrown.
154157
assertThrows(CryptoException::class.java) {
@@ -178,8 +181,8 @@ class UID2ClientTest {
178181
val client = withClient()
179182

180183
// Mock the DataEnvelope to fail to decrypt the given payload.
181-
whenever(networkSession.loadData(any(), any())).thenReturn(NetworkResponse(200, "somedata"))
182-
whenever(dataEnvelope.decrypt(anyOrNull<ByteArray>(), any(), any())).thenReturn(null)
184+
every { networkSession.loadData(any(), any()) }.returns(NetworkResponse(200, "somedata"))
185+
every { dataEnvelope.decrypt(any<ByteArray>(), any<String>(), any<Boolean>()) }.returns(null)
183186

184187
// Verify the expected CryptoException is thrown.
185188
assertThrows(PayloadDecryptException::class.java) {
@@ -198,10 +201,10 @@ class UID2ClientTest {
198201
val client = withClient()
199202

200203
val unencrypted = JSONObject(TestData.REFRESH_TOKEN_SUCCESS_DECRYPTED)
201-
whenever(dataEnvelope.decrypt(anyOrNull<ByteArray>(), any(), any())).thenReturn(
204+
every { dataEnvelope.decrypt(any<ByteArray>(), any<String>(), any<Boolean>()) }.returns(
202205
unencrypted.toString().toByteArray(),
203206
)
204-
whenever(networkSession.loadData(any(), any())).thenReturn(NetworkResponse(200, "some data"))
207+
every { networkSession.loadData(any(), any()) }.returns(NetworkResponse(200, "some data"))
205208

206209
val response = client.generateIdentity(
207210
IdentityRequest.Email("[email protected]"),
@@ -246,8 +249,8 @@ class UID2ClientTest {
246249
fun `test refresh with invalid data key`() = runTest(testDispatcher) {
247250
val client = withClient()
248251

249-
whenever(dataEnvelope.decrypt(any<String>(), any(), any())).thenReturn(null)
250-
whenever(networkSession.loadData(any(), any())).thenReturn(NetworkResponse(200, "some data"))
252+
every { dataEnvelope.decrypt(any<String>(), any(), any()) }.returns(null)
253+
every { networkSession.loadData(any(), any()) }.returns(NetworkResponse(200, "some data"))
251254

252255
// Verify that when an unexpected response is returned, the appropriate exception is thrown.
253256
assertThrows(PayloadDecryptException::class.java) {
@@ -260,8 +263,8 @@ class UID2ClientTest {
260263
val client = withClient()
261264

262265
val unencrypted = JSONObject(TestData.REFRESH_TOKEN_SUCCESS_DECRYPTED)
263-
whenever(dataEnvelope.decrypt(any<String>(), any(), any())).thenReturn(unencrypted.toString().toByteArray())
264-
whenever(networkSession.loadData(any(), any())).thenReturn(NetworkResponse(200, "some data"))
266+
every { dataEnvelope.decrypt(any<String>(), any(), any()) }.returns(unencrypted.toString().toByteArray())
267+
every { networkSession.loadData(any(), any()) }.returns(NetworkResponse(200, "some data"))
265268

266269
// Verify that the payload was successfully decrypted, and parsed.
267270
val identity = client.refreshIdentity(refreshToken, TestData.REFRESH_TOKEN_ENCRYPTED_SUCCESS_KEY)
@@ -282,8 +285,8 @@ class UID2ClientTest {
282285

283286
// Configure the network session to return a valid payload.
284287
val unencrypted = JSONObject(TestData.REFRESH_TOKEN_OPT_OUT_DECRYPTED)
285-
whenever(dataEnvelope.decrypt(any<String>(), any(), any())).thenReturn(unencrypted.toString().toByteArray())
286-
whenever(networkSession.loadData(any(), any())).thenReturn(NetworkResponse(200, "some data"))
288+
every { dataEnvelope.decrypt(any<String>(), any(), any()) }.returns(unencrypted.toString().toByteArray())
289+
every { networkSession.loadData(any(), any()) }.returns(NetworkResponse(200, "some data"))
287290

288291
// Verify that the payload was successfully decrypted, and parsed.
289292
val identity = client.refreshIdentity(refreshToken, TestData.REFRESH_TOKEN_ENCRYPTED_OPT_OUT_KEY)
@@ -295,7 +298,7 @@ class UID2ClientTest {
295298
fun `test version info - generate identity`() {
296299
testVersionInfo { client ->
297300
val unencrypted = JSONObject(TestData.REFRESH_TOKEN_SUCCESS_DECRYPTED)
298-
whenever(dataEnvelope.decrypt(anyOrNull<ByteArray>(), any(), any())).thenReturn(
301+
every { dataEnvelope.decrypt(any<ByteArray>(), any(), any()) }.returns(
299302
unencrypted.toString().toByteArray(),
300303
)
301304

@@ -310,7 +313,7 @@ class UID2ClientTest {
310313

311314
@Test
312315
fun `test version info - refresh identity`() {
313-
whenever(dataEnvelope.decrypt(any<String>(), any(), any())).thenReturn(
316+
every { dataEnvelope.decrypt(any<String>(), any(), any()) }.returns(
314317
TestData.REFRESH_TOKEN_SUCCESS_DECRYPTED.toByteArray(),
315318
)
316319

@@ -352,7 +355,7 @@ class UID2ClientTest {
352355
val client = withClient()
353356

354357
// Configure the network session to report a failure.
355-
whenever(networkSession.loadData(any(), any())).thenReturn(NetworkResponse(400))
358+
every { networkSession.loadData(any(), any()) }.returns(NetworkResponse(400))
356359

357360
// Verify that when a network failure occurs, the appropriate exception is thrown.
358361
assertThrows(RequestFailureException::class.java) {
@@ -370,7 +373,7 @@ class UID2ClientTest {
370373
val client = withClient()
371374

372375
// Configure the network session to return an invalid response.
373-
whenever(networkSession.loadData(any(), any())).thenReturn(
376+
every { networkSession.loadData(any(), any()) }.returns(
374377
NetworkResponse(200, "This is not encrypted"),
375378
)
376379

@@ -392,9 +395,9 @@ class UID2ClientTest {
392395
// Configure the network session to return a valid (encrypted) payload and allows us to capture the given
393396
// NetworkRequest.
394397
var networkRequest: NetworkRequest? = null
395-
whenever(networkSession.loadData(any(), any())).thenAnswer {
396-
networkRequest = it.arguments[1] as NetworkRequest?
397-
return@thenAnswer NetworkResponse(200, "some data")
398+
every { networkSession.loadData(any(), any()) }.answers {
399+
networkRequest = secondArg() as NetworkRequest?
400+
NetworkResponse(200, "some data")
398401
}
399402

400403
callback(client)

0 commit comments

Comments
 (0)