A small library that provides helper functions to work with Mockito in Kotlin.

Overview

Mockito-Kotlin

Download Nexus Snapshot

A small library that provides helper functions to work with Mockito in Kotlin.

Install

Mockito-Kotlin is available on Maven Central. For Gradle users, add the following to your build.gradle, replacing x.x.x with the latest version:

testImplementation "org.mockito.kotlin:mockito-kotlin:x.x.x"

Example

A test using Mockito-Kotlin typically looks like the following:

@Test
fun doAction_doesSomething(){ 
  /* Given */
  val mock = mock<MyClass> {
    on { getText() } doReturn "text"
  }
  val classUnderTest = ClassUnderTest(mock)
  
  /* When */
  classUnderTest.doAction()
  
  /* Then */
  verify(mock).doSomething(any())
}

For more info and samples, see the Wiki.

Building

Mockito-Kotlin is built with Gradle.

  • ./gradlew build builds and tests the project
  • ./gradlew publishToMavenLocal installs the maven artifacts in your local repository
  • ./gradlew check runs the test suite (See Testing below)

Versioning

Mockito-Kotlin roughly follows SEMVER

Testing

Mockito-Kotlin's test suite is located in a separate tests module, to allow running the tests using several Kotlin versions whilst still keeping the base module at a recent version.

  • ./gradlew check runs the checks including tests.

Usually it is enough to test only using the default Kotlin versions; CI will test against multiple versions. If you want to test using a different Kotlin version locally, set an environment variable KOTLIN_VERSION and run the tests.

Acknowledgements

mockito-kotlin was created and developed by nhaarman@ after which the repository was integrated into the official Mockito GitHub organization. We would like to thank Niek for the original idea and extensive work plus support that went into mockito-kotlin.

Comments
  • Matchers are not working for suspend functions

    Matchers are not working for suspend functions

    It seems that if you try to use "matchers" (any, eq, etc.) on suspend function mockito fails with "InvalidUseOfMatchersException".

    following test

    @Test
    fun otherTest() {
        val foo: Foo = mock {
            on { runBlocking { bar(any()) } } doReturn ("message")
        }
        Mockito.validateMockitoUsage()
    }
    

    with following interface definition

    interface Foo {
        suspend fun bar(arg: String): String
    }
    

    produces following error

    org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
    Invalid use of argument matchers!
    2 matchers expected, 1 recorded:
    -> at org.app.Tests$otherTest$i$1$1$1.doResume(Tests.kt:76)
    
    opened by kostya-misura 19
  • Coroutine/suspend function mocking support

    Coroutine/suspend function mocking support

    If you use non-inline lambdas that are not declared as suspend, the runBlocking { } around the test function doesn't help, rather we need to mock { on { runBlocking { suspendFun() } } } for each mock...

    done 2.0 
    opened by dave08 19
  • Add suspend answer; Fix #346

    Add suspend answer; Fix #346

    This code was inspired by:

    • Java wrapper part: https://github.com/square/retrofit/blob/8c93b59dbc57841959f5237cb141ce0b3c18b778/retrofit/src/main/java/retrofit2/HttpServiceMethod.java#L168
    • Kotlin wrapper part: https://github.com/square/retrofit/blob/8c93b59dbc57841959f5237cb141ce0b3c18b778/retrofit/src/main/java/retrofit2/KotlinExtensions.kt#L83-L98

    I used Java code because kotlin does not allow call suspend functions or lambdas by giving own Continuation. But Kotlin does it under the hood, so Java could do it as well. For example:

    fun foo(continuation: Continuation) {
      bar(continuation) //compilation error
    }
    
    suspend fun bar() {
    
    }  
    
    opened by neworld 18
  • Doesn't work for Android tests

    Doesn't work for Android tests

    I am using this lib successfully for unit tests, but when I try to use it for an instrumented Android test, I get the following: Use:

    import com.nhaarman.mockito_kotlin.mock
    val n: AppData = mock()
    

    Error:

    java.lang.NoClassDefFoundError: Failed resolution of: Lcom/nhaarman/mockito_kotlin/MockitoKt;
    at com.myproject.tests.Test.testSomething(Test.kt:91)
    at java.lang.reflect.Method.invoke(Native Method)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
    at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
    at android.support.test.internal.statement.UiThreadStatement.evaluate(UiThreadStatement.java:55)
    at android.support.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:270)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:27)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
    at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:59)
    at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:262)
    at com.jakewharton.u2020.U2020TestRunner.onStart(U2020TestRunner.java:22)
    at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1932)
    Caused by: java.lang.ClassNotFoundException: Didn't find class "com.nhaarman.mockito_kotlin.MockitoKt" on path: DexPathList[[zip file "/system/framework/android.test.runner.jar", zip file "/data/app/com.myproject.test-1/base.apk", zip file "/data/app/com.myproject-2/base.apk"],nativeLibraryDirectories=[/data/app/com.myproject.test-1/lib/x86, /data/app/com.myproject-2/lib/x86, /data/app/com.myproject.test-1/base.apk!/lib/x86, /data/app/com.myproject-2/base.apk!/lib/x86, /system/lib, /vendor/lib]]
    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:380)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
    ... 34 more
    
    opened by autonomousapps 16
  • Support for Answers in mock setup

    Support for Answers in mock setup

    It would be very useful to be able to do a doAnswer in the same way as a doReturn or a doThrow. Something like:

    private val userDao: UserDao = mock {
        on(this.save(any())) doAnswer { user ->
            UserModel(id = "userId", version = 1L, userData = user)
        }
    }
    

    At the moment I'm having to do this in an @Before or else in each test case.

    type:proposed-enhancement 
    opened by sazzer 15
  • Mocking final field of final class

    Mocking final field of final class

    Hello, I'm trying to use mockito-kotlin 2.2.0 in order to mock a final field in a final class of Crashlytics.

    class CrashlyticsCrashReportingServiceTest {
    
        private val crashlyticsCore: CrashlyticsCore = mock()
        private val crashlytics: Crashlytics = mock {
            on { core } doReturn crashlyticsCore
        }
    
        private val tested: CrashlyticsCrashReportingService =
            CrashlyticsCrashReportingService(crashlytics)
    
        @Test
        fun `should log exception to crashlytics when requested`() {
            // given
            val exception: IOException = mock()
    
            // when
            tested.reportCrash(exception)
    
            // then
            verify(crashlyticsCore).logException(exception)
        }
    
        @Test
        fun `given message is provided should log message and exception when requested`() {
            // given
            val message = "Message"
            val exception: IOException = mock()
    
            // when
            tested.reportCrash(exception, message)
    
            // then
            verify(crashlyticsCore).log(message)
            verify(crashlyticsCore).logException(exception)
        }
    }
    
    class CrashlyticsCrashReportingService(
        private val crashlyticsInstance: Crashlytics
    ): CrashReportingService {
    
        override fun reportCrash(throwable: Throwable, message: String?) {
            message?.let {
                crashlyticsInstance.core.log(message)
            }
            crashlyticsInstance.core.logException(throwable)
        }
    }
    

    I have added src/test/resources/mockito-extensions.org.mockito.plugins.MockMaker file with "mock-maker-inline" text inside of it. However I'm still getting

    org.mockito.exceptions.misusing.MissingMethodInvocationException: 
    when() requires an argument which has to be 'a method call on a mock'.
    For example:
        when(mock.getArticles()).thenReturn(articles);
    
    Also, this error might show up because:
    1. you stub either of: final/private/equals()/hashCode() methods.
       Those methods *cannot* be stubbed/verified.
       Mocking methods declared on non-public parent classes is not supported.
    2. inside when() you don't call method on mock but on some other object.
    
    
    	at com.nhaarman.mockitokotlin2.KStubbing.on(KStubbing.kt:70)
    	at com.example.base.crash.CrashlyticsCrashReportingServiceTest.<init>(CrashlyticsCrashReportingServiceTest.kt:15)
    	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    	at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:217)
    	at org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:266)
    	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    	at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:263)
    	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    	at org.junit.runners.Suite.runChild(Suite.java:128)
    	at org.junit.runners.Suite.runChild(Suite.java:27)
    	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
    

    How can I fix that?

    opened by karlkar 14
  • Strange NoSuchMethodError when using 2.2.0

    Strange NoSuchMethodError when using 2.2.0

    I've been trying to upgrade from 2.1.0 to 2.2.0 and now I have a few tests that fail with this exception:

    java.lang.NoSuchMethodError: com.nhaarman.mockitokotlin2.MockingKt.withSettings([Lkotlin/reflect/KClass;Ljava/lang/String;Ljava/lang/Object;Lorg/mockito/stubbing/Answer;ZLorg/mockito/mock/SerializableMode;Z[Lorg/mockito/listeners/InvocationListener;ZLcom/nhaarman/mockitokotlin2/UseConstructor;Ljava/lang/Object;Z)Lorg/mockito/MockSettings;
    
    	at com.qonto.qonto.ui.otp.setup.phonenumber.PhoneNumberPresenterTest.<init>(PhoneNumberPresenterTest.kt:180)
    	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    	at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:217)
    	at org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:266)
    	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    	at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:263)
    	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    	at org.junit.runners.Suite.runChild(Suite.java:128)
    	at org.junit.runners.Suite.runChild(Suite.java:27)
    	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
    

    This is on a test that does something like this:

        private val otpViewModel = mock<OTPSetupViewModel> {
            on { mustSwitchOtpFromAppToSms() } itAnswers { mustSwitchOtpFromAppToSms }
            on { createMfaBySms() } itAnswers { createMfaBySmsResponse }
            on { showError } itAnswers { showErrorLiveData }
        }
    

    Any idea?

    opened by BoD 14
  • How to mock a suspend function on an existing mock object?

    How to mock a suspend function on an existing mock object?

    I have mock A built and given to me. Now, I need to mock a suspend API to return a value foo.

    Example:

    @Inject lateinit var mockA: A // using dagger to provide mocks configured in a separate module.
    
    @Test
    fun test1() = runBlocking {
        // how do i mock a suspend method on mockA?
    }
    
    

    Originally posted by @andrewborba10 in https://github.com/nhaarman/mockito-kotlin/issues/269#issuecomment-429467218

    type:question 
    opened by Moes81 14
  • Mocking final classes

    Mocking final classes

    Hi, Kotlin classes are final by default, when i use this library to test kotlin classes, it gives me the following error:

    org.mockito.exceptions.base.MockitoException: 
    Cannot mock/spy class com.app.network.entity.Movies
    Mockito cannot mock/spy because :
     - final class
    

    How do i test this? Please assist

    type:invalid type:question 
    opened by ghost 14
  • Mocking Extension functions

    Mocking Extension functions

    Is it possible to stub Kotlin extension methods?

    Let's say I have an extension function:

    fun Context.findColor(color: Int) = resources.getColor(color)
    

    And I have a mock of an Context I would like to stub:

    val mock = mock<Context>()
    
    whenever(mock.findColor(color)).thenReturn(color)
    

    Right now it doesn't work. Is there a way to achieve this?

    type:question 
    opened by SirWellington 13
  • Verify Method called throws Null Pointer exception.

    Verify Method called throws Null Pointer exception.

    Method to Test from presenter

    ` override

    fun syncLocalOrders(syncOrders: SyncOrders) {
        if (syncOrders.orders.isNotEmpty()) {
            view.showProgressDialog("Syncing Successful Call's")
            repository.syncLocalOrder(syncOrders)
                    .subscribe({
                        var syncMessage = if (it.failure.count() > 0) {
                            "Call Synced Failed"
                        } else {
                            "Call synced successfully."
                        }
                        view.hideProgressDialog()
                        getUnsuccessfulCallData(false, syncMessage) //Null Pointer Exception
                        updateDatabase(it)
                    }, {
                        view.hideProgressDialog() // and enters here too after null pointer exception
                        view.showAlertDialog("Error", ErrorMessageFactory.createMessage(it))
                    })
        } else {
            getUnsuccessfulCallData(true, "")
        }
    }`
    

    ` @VisibleForTesting

    internal fun getUnsuccessfulCallData(showDialog: Boolean, syncMessage: String) {
        repository.getUnsuccessfulCallData()
                .subscribe({
                    if (it.noOrders.isNotEmpty()) {
                        syncUnsuccessfulCallData(it, syncMessage)
                    } else {
                        view.hideProgressDialog()
                        if (showDialog) {
                            view.showAlertDialog("", "no orders to sync")
                        } else {
                            if (syncMessage.isNotEmpty())
                                view.showSnackBar(syncMessage)
                        }
    
                    }
    
                }, {
                    it.printStackTrace()
                })
    }
    

    `

    ` @Test

    fun syncLocalOrders_OrderNotEmptySuccessTest() {
        val order = Order(
                outletId = 1,
                startDate = "Start Date",
                endDate = "End Date",
                syncLat = 9090.09009,
                syncLng = 909009.990,
                offRoute = 1,
                notes = "notes",
                remarks = "Remarks",
                totalPromotionDiscount = 9090.998,
                totalAmount = 90.90,
                inventory = null,
                promotionOrders = null
        )
        val listOfOrder = listOf(order, order)
    
        val syncOrder = SyncOrders(listOfOrder)
        val success = listOf(1, 2, 3, 4)
        val failure = listOf<Int>()
        val orderResponse = OrderResponse(success, failure)
        whenever(repository.syncLocalOrder(syncOrder)).thenReturn(Observable.just(orderResponse))
    
        presenter.syncLocalOrders(syncOrder)
        verify(view).showProgressDialog(anyString())
        verify(view).hideProgressDialog()
        verify(presenter, times(1)).getUnsuccessfulCallData(eq(false),  "Call synced successfully.")
        verify(presenter, times(1)).updateDatabase(orderResponse)
    
    }`
    

    The main issue here is whenever I try to run the test syncLocalOrders_OrderNotEmptySuccessTest(), the code enters to both subscribe and throwable of fun syncLocalOrders(syncOrders: SyncOrders) (this was got by keeping breakpoints.) And what I knew was the code enters to throwable after getting Null Pointer Exception on getUnsuccessfulCallData(false, syncMessage) and the test fails Saying something like view.hideProgressDialog() wanted 1 time but was 2 times. Can anybody tell me what am I doing wrong?

    type:question not-reproducible 
    opened by nawinkhatiwada 12
  • How to mock lambda call

    How to mock lambda call

    Hello, I have this function:

    override fun loadSensors(userId: String, param: (Result<MutableList<UserSensor>>) -> Unit) {
            // Blank
    }
    
        @get:Rule
        var hiltRule = HiltAndroidRule(this)
    
        @Rule @JvmField
        var mockitoRule = MockitoJUnit.rule()
    
        @Inject
        lateinit var repository: MockRepositoryImpl
    
        @Before
        fun before() {
            hiltRule.inject()
    
            MockitoAnnotations.openMocks(this)
    
            `when`(repository.loadSensors(anyString(), any())).thenAnswer {
                Result.Success("", mutableListOf(UserSensor(0), UserSensor(1)))
            }
    
            ActivityScenario.launch(MainActivity::class.java)
        }
    

    How to mock that thenAnswer would actually call my param argument?

    opened by cjacky475 0
  • Can you please provide suspending shortcuts for do* style stubbing APIs?

    Can you please provide suspending shortcuts for do* style stubbing APIs?

    Consider this sample:

      open class Foo {
        open suspend fun check(s: String): Int {
          delay(1)
          return s.length
        }
      }
    
      @Test
      fun bad() = runBlocking {
        val foospy = spy(Foo())
        foospy.stub { onBlocking { foospy.check(any()) } doReturn 42 }
        assertThat(foospy.check("a")).isEqualTo(42)
      }
    
      @Test
      fun good() = runBlocking {
        val foospy = spy(Foo())
        foospy.stub { runBlocking { doReturn(42).whenever(foospy).check(any()) } }
        assertThat(foospy.check("a")).isEqualTo(42)
      }
    

    The bad method fails because foospy.check calls the real method with a null and that throws a NPE. The good method works because we use the doReturn style and that doesn't call the real method.

    The onBlocking helper is only provided for the when-style stubbing. Can you please provide similar helper methods for doReturn and doAnswer? The sample shows how they can work, but I'm not sure about how they should be named. I'm assuming that the KStubbing class is meant to cover all the tricky cases that arise because of suspending functions.

    opened by fejesjoco 0
  • "Mockito cannot mock this class" after upgrading from Kotlin 1.6.21 to 1.7.0

    After upgrading from Kotlin 1.6.21 to 1.7.0 several tests failed in my project.

    Error log from 1.7.0: https://github.com/breucode/imisu/runs/7162625396

    Successful run in 1.6.21: https://github.com/breucode/imisu/runs/7162750526

    The failing tests are located here: https://github.com/breucode/imisu/blob/master/src/test/kotlin/de/breuco/imisu/api/routes/ServicesTest.kt

    opened by breucode 2
  • Mockito.mockStatic not working with Kotlin but it works in Java

    Mockito.mockStatic not working with Kotlin but it works in Java

    I was trying a mock a static method inside my Kotlin class for a unit test, but it seems the Java version of my Unit Test is successful but the Kotlin version is failing

    @RunWith(RobolectricTestRunner.class)
    public class MyTest {
    
        @Test
        public void givenStaticMethodWithArgs_whenMocked_thenReturnsMockSuccessfully() {
            RestAdapterFactory restAdapterFactoryMock = Mockito.mock(RestAdapterFactory.class);
            try (MockedStatic<RestAdapterFactory> utilities = Mockito.mockStatic(RestAdapterFactory.class)) {
                utilities.when(() -> RestAdapterFactory.getInstance(Mockito.any()))
                        .thenReturn(restAdapterFactoryMock);
    
                assertEquals(restAdapterFactoryMock, RestAdapterFactory.getInstance("fd"));
            }
        }
    }
    

    This test is running successfully but the Kotlin version of it below is failing

    Kotlin Version

    @Test
    fun givenStaticMethodWithArgs_whenMocked_thenReturnsMockSuccessfully() {
    val restAdapterFactoryMock = Mockito.mock(RestAdapterFactory::class.java)
    Mockito.mockStatic(RestAdapterFactory::class.java).use { utilities ->
    utilities.`when`<Any> { getInstance(Mockito.any()) }.thenReturn(restAdapterFactoryMock)
    Assert.assertEquals(restAdapterFactoryMock, getInstance("test"))
      }
    } 
    

    Getting the below exception:

    You cannot use argument matchers outside of verification or stubbing.
    Examples of correct usage of argument matchers:
        when(mock.get(anyInt())).thenReturn(null);
        doThrow(new RuntimeException()).when(mock).someVoidMethod(any());
        verify(mock).someMethod(contains("foo"))
    

    Can someone help with this ?

    opened by aakash1313 1
  • Kotlin - Unable to return value classes

    Kotlin - Unable to return value classes

    When returning a value class from a mocked method, class cast can not be done properly

    Sample code:

    value class Base64Data(val data: String)
    
    fun doSomething(data: Base64Data): Base64Data = Base64Data("test")
    
    /**
     * Workaround to support matching of value classes
     *
     * From: https://github.com/mockito/mockito-kotlin/issues/445#issuecomment-983619131
     */
    inline fun <Outer, reified Inner> eqValueClass(
        expected: Outer,
        crossinline access: (Outer) -> Inner,
        test: ((actual: Any) -> Boolean) -> Any? = ::argWhere
    ): Outer {
        val assertion: (Any) -> Boolean = { actual ->
            if (actual is Inner) {
                access(expected) == actual
            } else {
                expected == actual
            }
        }
        @Suppress("UNCHECKED_CAST")
        return test(assertion) as Outer? ?: expected
    }
    
        @Test
        fun `test something`() = runTest {
            // GIVEN
            val screenshotEncoded = Base64Data("screenshot-encoded")
            whenever(
                client.doSomething(
                   eqValueClass(levelData, { it.data })
                )
            ) doReturn screenshotEncoded
    
            // WHEN
            {...}
    }
    
    

    When executing that code and getting the mock the response is as follows:

    java.lang.ClassCastException: class com.king.uplevelmanager.util.Base64Data cannot be cast to class java.lang.String (com.king.uplevelmanager.util.Base64Data is in unnamed module of loader 'app'; java.lang.String is in module java.base of loader 'bootstrap')
    

    Tested returning a simple type like String (to discard matcher failing) and worked successfully.

    opened by kargath 3
  • how to verify a static method in kotlin

    how to verify a static method in kotlin

    Having a kotlin singleton with static methods

    internal object TestSingleton {
        @JvmStatic
        fun staticMethod1 (str: String) {
            println("+++ === +++ TestSingleton.staticMethod(), $str")
            staticMethod2 (str)
        }
    
        @JvmStatic
        fun staticMethod2 (str: String) {
            println("+++ === +++ TestSingleton.staticMethod2(), $str")
        }
    }
    

    In java test code:

        @Test
        public void test_staticMethod() {
    
            try (MockedStatic<TestSingleton> theMock = Mockito.mockStatic(TestSingleton.class, CALLS_REAL_METHODS)) {
    
                TestSingleton.staticMethod1("test");
                theMock.verify(() -> TestSingleton.staticMethod2(eq("test")), times(1));
            }
        }
    

    it runs fine but convert to kotlin it does not compile:

        @Test
        open fun test_staticMethod() {
            Mockito.mockStatic(TestSingleton::class.java, Mockito.CALLS_REAL_METHODS).use { theMock ->
                staticMethod1("test")
    
                theMock.verify(() -> TestSingleton.staticMethod(any(Context.class), "test"), times(1))
                // or
                theMock.verify(times(1), () -> TestSingleton.staticMethod(any(Context.class)) )
    
            }
        }
    

    [enter image description here]1 having mockito version testImplementation "org.mockito:mockito-inline:3.12.4".

    How to test/verify static method using mockito in kotlin?

    opened by lannyf77 2
Releases(4.1.0)
  • 4.1.0(Nov 26, 2022)

    Changelog generated by Shipkit Changelog Gradle Plugin

    4.1.0

    • 2022-11-26 - 6 commit(s) by Niklas Seyfarth, Tim van der Lippe, Vetle Leinonen-Roeim, taeyeonKim, wrongwrong
    • Update Shipkit versions (#468)
    • Also trigger release on 4.x tags (#466)
    • Ease verify inOrder for suspending functions (#464)
    • Upgrading Gradle to 6.9.2, Kotlin to 1.4.20, junit to 4.13.2 and mockito to 4.4.0 (#458)
    • Add LenientStubber (#454)
    • Remove jcenter (#450)
    • Add support for per-mock strictness (#325)
    Source code(tar.gz)
    Source code(zip)
  • 4.0.0(Oct 12, 2021)

  • 3.2.0(May 5, 2021)

  • 3.1.0(Apr 1, 2021)

  • 3.0.0(Mar 29, 2021)

  • 2.2.11(Mar 23, 2021)

  • 2.2.10(Mar 23, 2021)

  • 2.2.9(Mar 23, 2021)

  • 2.2.8(Mar 22, 2021)

  • 2.2.7(Mar 22, 2021)

  • 2.2.6(Mar 22, 2021)

  • 2.2.0(Sep 8, 2019)

    • Add reified support for refEq like other matchers https://github.com/nhaarman/mockito-kotlin/pull/329
    • Make after() return type non-null https://github.com/nhaarman/mockito-kotlin/pull/351
    • Support lenient in mock and withSettings https://github.com/nhaarman/mockito-kotlin/pull/353
    Source code(tar.gz)
    Source code(zip)
  • 2.1.0(Dec 31, 2018)

  • 2.0.0(Oct 30, 2018)

    Version 2.x introduces some breaking changes:

    • The artifact to include is now com.nhaarman.mockitokotlin2:mockito-kotlin:x.x.x;
    • The main package to import from is now com.nhaarman.mockitokotlin2;
    • Mockito-Kotlin does not depend on kotlin-reflect anymore. This solves a few conflict issues when using different Kotlin versions. The artifact mockito-kotlin-kt1.1 is therefore dropped.
      • This removes the creation of arbitrary instances through reflection, which was not necessary anyway due to the T as null quirk.

    To include this, use the following:

    testCompile 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.0.0'
    

    If you included a dependency on kotlin-reflect for Mockito-Kotlin only, you can remove it.

    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-RC3(Oct 9, 2018)

    Version 2.x will introduce some breaking changes:

    • The artifact to include is now com.nhaarman.mockitokotlin2:mockito-kotlin:x.x.x;
    • The main package to import from is now com.nhaarman.mockitokotlin2;
    • Mockito-Kotlin does not depend on kotlin-reflect anymore. This solves a few conflict issues when using different Kotlin versions. The artifact mockito-kotlin-kt1.1 is therefore dropped.
      • This removes the creation of arbitrary instances through reflection, which was not necessary anyway due to the T as null quirk.

    To try this release, use the following:

    testCompile 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.0.0-RC3'
    

    If you included a dependency on kotlin-reflect for Mockito-Kotlin only, you can remove it.

    Changes since 2.0.0-RC2:

    • Updates Mockito to 2.23.0
      • This enables support for stable coroutines
    • Include argThat(ArgumentMatcher<T>) function #281
    • Remove a deprecated doReturn function (#274)

    This should be the last RC before 2.0.0 is released, which will be some time after Kotlin 1.3 is released.

    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-RC2(Oct 9, 2018)

    Version 2.x will introduce some breaking changes:

    • The artifact to include is now com.nhaarman.mockitokotlin2:mockito-kotlin:x.x.x;
    • The main package to import from is now com.nhaarman.mockitokotlin2;
    • Mockito-Kotlin does not depend on kotlin-reflect anymore. This solves a few conflict issues when using different Kotlin versions. The artifact mockito-kotlin-kt1.1 is therefore dropped.
      • This removes the creation of arbitrary instances through reflection, which was not necessary anyway due to the T as null quirk.

    To try this release, use the following:

    testCompile 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.0.0-RC2'
    

    If you included a dependency on kotlin-reflect for Mockito-Kotlin only, you can remove it.

    Changes since 2.0.0-RC1:

    • Updates Mockito to 2.21.0
    • Inline whenever to let Mockito's UnfinishedStubbing messages work (#278)
    • Replace OngoingStubbing.doReturn(List) with doReturnConsecutively (#279)
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-RC1(Jun 21, 2018)

    Version 2.x will introduce some breaking changes:

    • The artifact to include is now com.nhaarman.mockitokotlin2:mockito-kotlin:x.x.x;
    • The main package to import from is now com.nhaarman.mockitokotlin2;
    • Mockito-Kotlin does not depend on kotlin-reflect anymore. This solves a few conflict issues when using different Kotlin versions. The artifact mockito-kotlin-kt1.1 is therefore dropped.
      • This removes the creation of arbitrary instances through reflection, which was not necessary anyway due to the T as null quirk.

    To try this release, use the following:

    testCompile 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.0.0-RC1'
    

    If you included a dependency on kotlin-reflect for Mockito-Kotlin only, you can remove it.

    Changes since 2.0.0-alpha04:

    • Updates Mockito to 2.19.0
    • Support mocking with constructor arguments. This breaks code that currently uses useConstructor = true, which can simply be replaced by useConstructor = parameterless(). (#266)
    Source code(tar.gz)
    Source code(zip)
  • 1.6.0(Jun 21, 2018)

  • 2.0.0-alpha04(May 10, 2018)

    • Makes inOrder inline (#248)
    • Adhere to ArgumentMatcher contract (#253)
    • Includes overloads for argumentCaptor (#254)
    com.nhaarman.mockitokotlin2:mockito-kotlin:2.0.0-alpha04
    
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0-alpha03(Feb 3, 2018)

  • 2.0.0-alpha02(Dec 3, 2017)

  • 2.0.0-alpha01(Nov 30, 2017)

    Version 2.x will introduce some breaking changes:

    • The artifact to include is now com.nhaarman.mockitokotlin2:mockito-kotlin:x.x.x;
    • The main package to import from is now com.nhaarman.mockitokotlin2;
    • Mockito-Kotlin does not depend on kotlin-reflect anymore. This solves a few conflict issues when using different Kotlin versions. The artifact mockito-kotlin-kt1.1 is therefore dropped.
      • This removes the creation of arbitrary instances through reflection, which was not necessary anyway due to the T as null quirk.

    To try this release, use the following:

    testCompile 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.0.0-alpha01'
    

    If you included a dependency on kotlin-reflect for Mockito-Kotlin only, you can remove it.

    Source code(tar.gz)
    Source code(zip)
  • 1.5.0(Jun 3, 2017)

    • same() now returns T instead of T?
    • Updates Mockito to 2.8.9
    • Introduces a new artifact for usage with Kotlin 1.1.x:
    compile 'com.nhaarman:mockito-kotlin-kt1.1:x.x.x'
    
    Source code(tar.gz)
    Source code(zip)
  • 1.4.0(Apr 1, 2017)

  • 1.3.0(Apr 1, 2017)

  • 1.2.0(Apr 1, 2017)

  • 1.1.0(Dec 27, 2016)

  • 1.0.1(Dec 12, 2016)

  • 1.0.0(Dec 6, 2016)

    This is the first major release for Mockito-Kotlin.

    What is Mockito-Kotlin?

    Mockito-Kotlin is a wrapper library around Mockito.

    It provides top-level functions to allow for a more idiomatic approach while using Mockito in Kotlin. Furthermore, Mockito returns null values for calls to method like any(), which can cause NullPointerExceptions when passing them to non-nullable parameters. This library solves that issue by trying to create actual instances to return.

    Mockito-Kotlin does not intend to alter any of the functionality that Mockito provides, except in places where crucial for working with Kotlin.

    See the Wiki to find out how to work with Mockito-Kotlin.

    Source code(tar.gz)
    Source code(zip)
  • 1.0.0-RC1(Dec 6, 2016)

Owner
mockito
Mockito framework
mockito
Kamper - a small KMM/KMP library that provides performance monitoring for your app.

?? Kamper Kamper is a KMP/KMM library that implements a unified way to track application performances. The solution is based on plugin design patterns

S. Mellouk 31 Jun 10, 2022
[Android Library] A SharedPreferences helper library to save and fetch the values easily.

Preference Helper A SharedPreferences helper library to save and fetch the values easily. Featured in Use in your project Add this to your module's bu

Naveen T P 13 Apr 4, 2020
AppCode helper for Kotlin/Native and Xcode

Kotlin Xcode compatibility Gradle plugin The plugin is used by AppCode to set up Kotlin/Native project along with Xcode Sources A multi-build sample w

Kotlin 21 Oct 23, 2022
A somewhat copy past of Jetbrain's code from the kotlin plugin repo to make it humanly possible to test Intellij IDEA kotlin plugins that work on kotlin

A somewhat copy past of Jetbrain's code from the kotlin plugin repo to make it humanly possible to test Intellij IDEA kotlin plugins that work on kotlin

common sense OSS 0 Jan 20, 2022
TensorFlow Lite Helper for Android to help getting started with TesnorFlow.

TensorFlow Lite Helper for Android This library helps with getting started with TensorFlow Lite on Android. Inspired by TensorFlow Lite Android image

Ahmed Gamal 26 Nov 19, 2022
Android SharedPreferences Helper

PocketDB Android SharedPreferences Helper This is SharedPreferences Helper like a database noSql. Support AES encryption Latest Version Download depen

Muhammad Utsman 9 Jun 20, 2021
A Kotlin work manager library for Android with progress notifications and Hilt support.

Boot Laces A kotlin work manager library for Android that includes notifications and Hilt support. User Instructions Add the JitPack repository to you

Chris Basinger 35 Oct 8, 2022
A kotlin library of extension functions that add smalltalk style methods to objects.

KtTalk A kotlin library of extension functions that add smalltalk style methods to objects. Motivation Smalltalk is a pure OO language in which everyt

null 11 Oct 16, 2021
ListUtil.kt ListUtils - Advance list functions from kotlin standard library

ListUtils - Advance list functions from kotlin standard library A set of utility functions to work with lists in a robust way. It is based on a patter

Zain Ul Hassan 1 May 6, 2022
A set of extension properties on Int, Long, Double, and Duration, that makes it easier to work with Kotlin Duration

Kotlin Duration Extensions Gradle Groovy repositories { mavenCentral() } implementation 'com.eygraber:kotlin-duration-extensions:1.0.1' Kotlin rep

Eliezer Graber 8 Nov 8, 2022
Extension functions over Android's callback-based APIs which allows writing them in a sequential way within coroutines or observe multiple callbacks through kotlin flow.

callback-ktx A lightweight Android library that wraps Android's callback-based APIs into suspending extension functions which allow writing them in a

Sagar Viradiya 171 Oct 31, 2022
Dots indicator that shows the current position on a View Pager. It does all the work for you with a few customisations.

Dots What is Dots? Dots is a library that helps in implementing a simple yet effective dots indicator for the View Pagers used in your android code. I

Deepan 23 Feb 16, 2022
Reapp is everything you need to build amazing apps with React: a collection of packages that work together, our UI kit, and a CLI that scaffolds your app and includes a server and build system.

What is it? Reapp is everything you need to build amazing apps with React: a collection of packages that work together, our UI kit, and a CLI that sca

reapp 3.4k Nov 20, 2022
Use Flink's Stateful Functions as a control-plane technology for operating a streaming-platform

statefun-ops Use ?? Flink Stateful Functions as a control-plane technology for operating a streaming-platform based on Apache Kafka. Walkthrough Ensur

Dylan Meissner 8 Oct 1, 2022
Muhammad Ariananda 7 Jul 17, 2022
Maildroid is a small robust android library for sending emails using SMTP server

Maildroid ?? Maildroid is a small robust android library for sending emails using SMTP server ?? Key Features • Add to your project • Documentation •

Nedim 174 Dec 22, 2022
Small lib for recovering stack trace in exceptions thrown in Kotlin coroutines

Stacktrace-decoroutinator Library for recovering stack trace in exceptions thrown in Kotlin coroutines. Supports JVM(not Android) versions 1.8 or high

null 104 Dec 24, 2022
LanServers - A small plugin written in Kotlin that runs on all major Minecraft Servers

LanServers This is a small plugin written in Kotlin that runs on all major Minec

Redstonecrafter0 6 Mar 12, 2022
AbstractMvp 0.8 0.0 Kotlin is a library that provides abstract components for MVP architecture realization, with problems solutions that are exist in classic MVP.

MinSDK 14+ AbstractMvp AbstractMvp is a library that provides abstract components for MVP architecture realization, with problems solutions that are e

Robert 12 Apr 5, 2022