- Which SDK this is regarding: Android SDK
- SDK Version: version 2.0.0
- Platform Version: Android 11
Hello everyone, we just upgraded our Auth0 Android lib to version 2 from version 1.30, and some of our unit tests that use OkHttp'
s MockWebServer
broke, here are the details:
- The first test fails with a
java.lang.ExceptionInInitializerError
which in turn is caused byjava.lang.RuntimeException: Method getMainLooper in android.os.Looper not mocked.
- Next three tests fail with
java.lang.NoClassDefFoundError: Could not initialize class com.auth0.android.request.internal.DefaultThreadSwitcher
- The rest of the tests are stuck until cancelled.
For context, we use RxJava3 and Android Jetpack libs such as LiveData in our code base, and Retrofit for REST API. For our unit tests we use mockk and JUnit5.
Here is a code snippet on how our test looks like:
class AuthManagerTest {
...
private lateinit var authManager: AuthManager
private lateinit var config: Auth0Config
private lateinit var server: MockWebServer
@MockK
private lateinit var context: Context
@MockK
private lateinit var credentialsManager: SecureCredentialsManager
...
...
@BeforeEach
fun setup() {
MockKAnnotations.init(this)
every { context.getSharedPreferences(any(), any()) } returns mockk()
every { credentialsManager.authToken } returns null
every { credentialsManager.userId } returns null
every { credentialsManager.refreshToken } returns null
every { credentialsManager.saveCredentials(any()) } just Runs
...
mockkObject(Credentials.Companion)
every { Credentials.fromAuth0Creds(any(), any()) } returns mockk()
server = MockWebServer().apply {
// we didn't use useHttps before but with the new version of Auth0 it seems https is mandatory
useHttps(testSslSocketFactory(), false)
start()
}
...
}
Here are the first tests in the aforementioned class:
@Test
fun `sendEmailCode returns EmailSent when response is successful`() {
server.enqueue(mockResponse(200, email_success_response))
val emailResult = authManager.sendEmailCode("me@example.org").blockingGet()
as EmailResult.EmailSent
assertEquals("me@example.org", emailResult.email)
assertNoToken()
}
@Test
fun `sendEmailCode returns InvalidEmail when response gives invalid email error`() {
server.enqueue(mockResponse(400, email_invalid_response))
val result = authManager.sendEmailCode("me.org").blockingGet()
as EmailResult.InvalidEmail
assertEquals("bad.email", result.code)
assertEquals("blah blah", result.description)
assertNoToken()
}
@Test
fun `sendEmailCode returns NetworkError when server is down`() {
server.shutdown()
val result = authManager.sendEmailCode("me@example.org").blockingGet()
assertTrue(result is EmailResult.NetworkError)
assertNoToken()
}
@Test
fun `sendEmailCode returns UnknownError when response gives unknown error`() {
server.enqueue(mockResponse(400, email_unknown_response))
val result = authManager.sendEmailCode("me@example.org").blockingGet()
as EmailResult.UnknownError
assertEquals("bad.send", result.code)
assertEquals("error in send - No enum match for: links", result.description)
assertNoToken()
}
@Test
fun `login with code returns Success when response is successful`() {
server.enqueue(mockResponse(200, email_code_success))
val credSlot = slot<Auth0Credentials>()
val regionSlot = slot<String>()
every {
credentialsManager.saveCredentials(
Credentials.fromAuth0Creds(capture(credSlot), capture(regionSlot))
)
} just Runs
val result = authManager.login("email", "1234").blockingGet()
as AuthResult.Success
assertNotNull(result)
verify(exactly = 1) { credentialsManager.saveCredentials(any()) }
val cred = credSlot.captured
assertEquals("jwt.t0k3n", cred.idToken)
assertEquals("4cc3ssToken", cred.accessToken)
assertEquals("reeefreshToken", cred.refreshToken)
assertEquals("nz", regionSlot.captured)
}
I tried adding @ExtendWith(InstantExecutorExtension::class, RxImmediateScheduler::class)
in the class declaration like this:
@ExtendWith(InstantExecutorExtension::class, RxImmediateScheduler::class)
class AuthManagerTest {
But afterwards, all tests return with “Test ignored” in the logs:
Test ignored.
java.lang.InstantiationException
at sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:48)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.junit.platform.commons.util.ReflectionUtils.newInstance(ReflectionUtils.java:513)
at org.junit.platform.commons.util.ReflectionUtils.newInstance(ReflectionUtils.java:488)
at org.junit.jupiter.engine.extension.MutableExtensionRegistry.registerExtension(MutableExtensionRegistry.java:176)
at java.util.ArrayList.forEach(ArrayList.java:1257)
at org.junit.jupiter.engine.extension.MutableExtensionRegistry.createRegistryFrom(MutableExtensionRegistry.java:117)
at org.junit.jupiter.engine.descriptor.ExtensionUtils.populateNewExtensionRegistryFromExtendWithAnnotation(ExtensionUtils.java:77)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.prepare(ClassBasedTestDescriptor.java:143)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.prepare(ClassBasedTestDescriptor.java:78)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$1(NodeTestTask.java:111)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:111)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:79)
at java.util.ArrayList.forEach(ArrayList.java:1257)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:75)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
Also, I’ve posted this in stackoverflow but got no answer. If crossposting is not allowed then just remove this post. I just figured that this forum might be a better venue to ask questions regarding Auth0 library. Thanks.