Code Monkey home page Code Monkey logo

mockito-kotlin's Introduction

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, add the -PtestKotlinVersion=1.2.3 argument to the Gradle invocation while running 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.

mockito-kotlin's People

Contributors

amokrane avatar andreprinz avatar angryziber avatar braisgabin avatar desilvai avatar ghostbuster91 avatar hennr avatar jossiwolf avatar lukas-krecan avatar mockitoguy avatar neworld avatar nhaarman avatar pablisco avatar panelpl avatar rajin9601 avatar rongi avatar sghill avatar shestee avatar sothawo avatar taeyeon-kim avatar tapchicoma avatar tatsuyafujisaki avatar thecodewarrior avatar timvdlippe avatar twisterrob avatar unlimitedsola avatar vdubedout avatar vetler avatar viniciussoares avatar wesalvaro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mockito-kotlin's Issues

What is the minimum java version? (6, 7)

There were no methods like mock(...) in autocompletion until I changed sourceCompatibility from 1.6 to 1.7
Then I change it back to 1.6 and everything still works.

Before it I tried to restart idea&clean cache etc.

Fallback to passed value for eq()

e.g.:

- inline fun <reified T : Any> eq(value: T): T = Mockito.eq(value) ?: createInstance<T>() 
+ fun <T : Any?> eq(value: T): T = Mockito.eq(value) ?: value

This way we can also call eq with a nullable value.

Stubbing with any() on nullable values don't work with nulls since 0.6.0

I don't know, it a bug or feature.

I have an interface:

interface Api {
  fun getFeed(page: Int, score: Int?):Observable<Feed>
}

Stubbing:

whenever(api.getFeed(any(), any()).thenReturn(empty())

If I call with null param: api.getFeed(0, null), I got null.
With not null works fine: api.getFeed(0, 0).

All pre 0.6.0 versions worked.

If I stub with whenever(api.getFeed(any(), isNull()).thenReturn(empty()) - works

Attempting to verify mocked calls with a class that has a string array parameter in its constructor throws UnsupportedOperationException

Hi,

I'm running into an issue where I'm trying to verify mocked calls on an object with the use of eq.

My test looks like:

data class Foo(val baz: Array<String>)

val bar = Foo(arrayOf("a", "b"))

@Test fun test() {
    verify(mock).method(eq(bar))
}

This fails with

java.lang.UnsupportedOperationException: Cannot create a generic array for Array. Use createArrayInstance() or anyArray() instead.
    at com.nhaarman.mockito_kotlin.CreateInstanceKt.toArrayInstance(CreateInstance.kt:124)
    at com.nhaarman.mockito_kotlin.CreateInstanceKt.createInstance(CreateInstance.kt:61)
    at com.nhaarman.mockito_kotlin.CreateInstanceKt.createNullableInstance(CreateInstance.kt:162)
    at com.nhaarman.mockito_kotlin.CreateInstanceKt.newInstance(CreateInstance.kt:137)
    at com.nhaarman.mockito_kotlin.CreateInstanceKt.createInstance(CreateInstance.kt:63)

Is there something that can be done about this?

Accept nullable type for anyArray()

Currently, anyArray() does not accept anyArray<String?>().

inline fun <reified T : Any?> anyArray(): Array<T> = Mockito.any(Array<T>::class.java) ?: arrayOf()

Add `doThrow` infix methods to OngoingStubbing

I like the mocker builder, with it's infix doReturn statements, and I'd like to see something similar for the throw actions.

I'd also like to allow a KClass to be passed in, just to be a little more kotliny.

mock {
    // currently
    on { myMethod() }.thenThrow(NotImplementedError::class.java)

    // proposed
    on { myMethod() } doThrow NotImplementedError::class
}

Mocking function literals

Hi @nhaarman,

I'm hitting a roadblock trying to use Mockito Kotlin to accept any function literal at per #54. The exception is:

org.mockito.exceptions.base.MockitoException: 
ClassCastException occurred while creating the mockito mock :
  class to mock : 'kotlin.jvm.functions.Function0', loaded by classloader : 'sun.misc.Launcher$AppClassLoader@7852e922'
  created class : 'kotlin.jvm.functions.Function0$MockitoMock$1488133923', loaded by classloader : 'MultipleParentClassLoader{parents=[sun.misc.Launcher$AppClassLoader@7852e922, org.robolectric.internal.bytecode.InstrumentingClassLoader@1f28c152]}'
  proxy instance class : 'kotlin.jvm.functions.Function0$MockitoMock$1488133923', loaded by classloader : 'MultipleParentClassLoader{parents=[sun.misc.Launcher$AppClassLoader@7852e922, org.robolectric.internal.bytecode.InstrumentingClassLoader@1f28c152]}'
  instance creation by : ObjenesisInstantiator

You might experience classloading issues, please ask the mockito mailing-list.

This verification in question is trying to use the suggested syntax from the earlier issue:

verify(mockCart).setQuantity(product, 1, any<() -> Unit>())

This is using:

  • 'org.mockito:mockito-core:1.10.19'
  • 'com.nhaarman:mockito-kotlin:0.7.0'

I've tried disabling the class cache after having a search for that exception, but this doesn't help:

class MockitoConfiguration : DefaultMockitoConfiguration() {
    override fun enableClassCache(): Boolean {
        return false
    }
}

Please could you help me identify if this is an issue with Mockito Kotlin or Roboelectric?

Thanks,
Oli

Improve argument captors

At the moment the behavior of using argument captors differs between the Kotlin and Java versions.
For example, the below Kotlin test fails, while the corresponding Java test passes:

@Test
fun testKotlin() {
    /* Given */
    val date: Date = mock()

    /* When */
    date.time = 5L
    date.time = 7L

    /* Then */
    verify(date, times(2)).time = capture {
        expect(it).toBe(7L)
    }
}
@Test
public void testJava() {
    /* Given */
    Date date = mock(Date.class);

    /* When */
    date.setTime(5L);
    date.setTime(7L);

    /* Then */
    ArgumentCaptor<Long> captor = ArgumentCaptor.forClass(Long.class);
    verify(date, times(2)).setTime(captor.capture());
    assert captor.getValue() == 7L;
}

The reason is that the Java version matches the latest captured value, while the current Kotlin version matches the first.

CreateInstance.easiestConstructor doesn't return the easiest constructor

I suppose that if a class has default constructor then it should be the easiest constructor.

For example this test fails from time to time:

class CreatorInstanceTest {
    @Test
    fun create() {
        createInstance(Event::class)
    }
}

class Event() {
    var time: DateTime? = null
    constructor(time: DateTime) : this() {
        this.time = time
    }
}

The result of easiestConstructor depends on the order of constructors in a list, and the method createInstance fails trying to create an Event by the second constructor.

Cannot make a java.lang.Class constructor accessible

i tried verify method call with Class argument

interface I {
    fun call()
}

open class Tested {
    fun doit(i: Class<I>) {
    }
}

@Test
class Test {
    fun t() {
        val tested:Tested = mock()
        verify(tested).doit(any())
    }
}

Annotation Support

Having annotation support, like Mockito does, would be awesome!!

Thank you for the great work!

Kotlin version

looks like your lib can be build only with Kotlin 1.0.2, but the actual version of Kotlin is 1.0.3

java.lang.AbstractMethodError: abstract method when just compile mockito-kotlin library in espresso instrumental test

Hi Haarman,

I found an issue, as per reported in
http://stackoverflow.com/questions/38136983/java-lang-abstractmethoderror-abstract-method-when-running-espresso-on-kotlin-w

You could get the code from
https://github.com/elye/kotlinespressomock

And then just add your "library" in the build.gradle

androidTestCompile ("com.nhaarman:mockito-kotlin:0.4.1") {
exclude group: "org.jetbrains.kotlin", module: 'kotlin-stdlib'
}

And run the instrumental test, MainActivityTest. You'll see the error.

Then it will fail. Inform you, in case you found the issue and solution. Feel free to update the stackoverflow when some solution is found. Thanks!!

any() doesn't seem to work with latest Mockito (2.0.94-beta)

Mockito have recently refactored the MockUtils class to be a static utility class (with a private constructor):

mockito/mockito@3fe3b62#diff-321079f7242b016035f4577222dfe7a3R26

However, mockito-kotlin tries to instantiate an instance of it - see CreateInstance.kt line 180:

return MockUtil().createMock(creationSettings).apply...

This causes the following runtime error when executing a test which calls the any() method:

java.lang.IllegalAccessError: tried to access method org.mockito.internal.util.MockUtil.<init>()V from class com.nhaarman.mockito_kotlin.CreateInstanceKt
    at com.nhaarman.mockito_kotlin.CreateInstanceKt.uncheckedMock(CreateInstance.kt:180)
    at com.nhaarman.mockito_kotlin.CreateInstanceKt.createInstance(CreateInstance.kt:58)

The fix should just be to call the static method instead - MockUtil.createMock(creationSettings).apply...

KStubbing: make `val mock` public

KStubbing not working for builder methods now, my use-case

val intent: Intent = mock() {
            on { putExtra(any(), any<Parcelable>()) } doReturn intent
            on { putExtra(any(), any<String>()) } doReturn intent
            on { putExtra(any(), any<Int>()) } doReturn intent
        }

In this case intent are not inited yet co i can't do it this way
I see possible solution as

val intent: Intent = mock() {
            on { putExtra(any(), any<Parcelable>()) } doReturn mock
            on { putExtra(any(), any<String>()) } doReturn mock
            on { putExtra(any(), any<Int>()) } doReturn mock
        }

but mock is private field
As an option

val intent: Intent = mock() {
            on { putExtra(any(), any<Parcelable>()) } doReturnSelf()
            on { putExtra(any(), any<String>()) } doReturnSelf()
            on { putExtra(any(), any<Int>()) } doReturnSelf()
        }

only mock interfaces

Why I cant mock non final classes?

It was working on java and now with kotlin it just run the code that should not run on the mocked instances.

I dont want to create an interface for every object, or should i?

Mocked methods that return nullable collections return non-null value by default

Given there is an interface

interface Service {
    fun getStrings(): Collection<String>?
    fun getStuff(): Stuff
}

data class Stuff(val a: String)

and a test that mocks the interface and calls and checks its methods sequentially

class MockitoKotlinTest {
    @Test fun `check mocking`() {
        val client = mock<Service>()

        assertThat(client.getStuff()).isNull()
        assertThat(client.getStrings()).isNull() // <-- fails here
    }
}

the assertThat(client.getStrings()).isNull() assertion will fail because by default mockito-kotlin makes it return LinkedList rather than null, despite the fact that interface explicitly allows null as return value. If I do something like

        whenever(client.getStrings()).thenReturn(null)

then test passes as expected, but it would be great if default return value for nullable collections were nulls.

Affected versions: 0.10.0, 0.10.1, 0.12.2

`uncheckedMock()` is not safe.

This issue investigates the cause of #24.

The uncheckedMock function bypasses the internal Mockito state checks to mock objects during verification. No interaction with these mocks is allowed, by the internals of Mockito.

However, when creating an unchecked mock of a Throwable class which takes a Throwable itself as a parameter, the Throwable class calls toString() on the unchecked mock, causing the exception below.

class SomeThrowable : Throwable {

    constructor(cause: Throwable) : super(cause) {
    }
}

class SomeTest {

    @Test
    fun test() {
        any<SomeThrowable>()
    }
}

Stack trace:

java.lang.reflect.InvocationTargetException
    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 kotlin.reflect.jvm.internal.FunctionCaller$Constructor.call(FunctionCaller.kt:63)
    at kotlin.reflect.jvm.internal.KCallableImpl$DefaultImpls.call(KCallableImpl.kt:65)
    at kotlin.reflect.jvm.internal.KFunctionImpl.call(KFunctionImpl.kt:30)
    at kotlin.reflect.jvm.internal.KCallableImpl$DefaultImpls.callBy(KCallableImpl.kt:101)
    at kotlin.reflect.jvm.internal.KFunctionImpl.callBy(KFunctionImpl.kt:30)
    at com.nhaarman.mockito_kotlin.CreateInstanceKt.newInstance(CreateInstance.kt:136)
    at com.nhaarman.mockito_kotlin.CreateInstanceKt.createInstance(CreateInstance.kt:60)
    at tmp.SomeTest.test(SomeTest.kt:45)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    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.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.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:119)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Invalid use of argument matchers!
0 matchers expected, 1 recorded:
-> at tmp.SomeTest.test(SomeTest.kt:44)

This exception may occur if matchers are combined with raw values:
    //incorrect:
    someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
    //correct:
    someMethod(anyObject(), eq("String by matcher"));

For more info see javadoc for Matchers class.

    at java.lang.Throwable.<init>(Throwable.java:311)
    at SomeThrowable.<init>(SomeTest.kt:33)

Relevant Throwable constructor:

public Throwable(Throwable cause) {
    fillInStackTrace();
    detailMessage = (cause==null ? null : cause.toString());
    this.cause = cause;
}

Call to createInstance() from lambda fails

The following test fails despite to an instance creator being registered:

@Test
fun test() {
    MockitoKotlin.registerInstanceCreator { CreateInstanceTest.ForbiddenConstructor(2) }

    val mock = mock<TestClass> {
        on { doSomething(any()) } doReturn Unit
    }
}

interface TestClass {

    fun doSomething(c: CreateInstanceTest.ForbiddenConstructor)
}

Error message:

com.nhaarman.mockito_kotlin.MockitoKotlinException: 

        Could not create an instance of class CreateInstanceTest.ForbiddenConstructor, because of an error with the following message:

            "Forbidden."

        Try registering an instance creator yourself, using MockitoKotlin.registerInstanceCreator<CreateInstanceTest.ForbiddenConstructor> {...}.

Update to 1.0.0 ?

When do you release something with 1.0.0 ? Not the beta..

Thanks!

Tweak stubbing idiom to allow for more kotlin regular expression

Hello,

I've been independently working on getting kotlin working with Mockito, and have done very little work in comparison to your work.

One thing I have got that I think your repo could use however is an idiom around setting up stubbed and mocked methods:

val fileTracker = mock<LastModifiedTimeTracker> {
    on { fileWasModified() }.thenReturn(true)
}

this is implemented with the relatively simple extension methods:

inline fun <reified T : Any> mock(stubbing: KStubbing<T>.() -> Unit) : T
        = Mockito.mock(T::class.java).apply { stubbing.invoke(KStubbing(this)) }

class KStubbing<TMock>(private val mock: TMock) {
    fun <TMethodReturn> on(methodCall: TMethodReturn) = Mockito.`when`(methodCall)
    fun <TMethodReturn> on(methodCall: TMock.() -> TMethodReturn) = Mockito.`when`(mock.methodCall());
}

i have not done extensive testing, but in thinking about it, the call order that mockito needs so badly should be preserved.

  1. on the first line, a mock is created.
  2. using that mock as a return value, the apply method is called
  3. stubbing.invoke is effectively when(methodCall)
  4. the specifics of both the on methods will have the arguments executed first, meaning aMock.call() will happen before Mockito.when, as is expected.

another win here is that unit is a type that is a subtype of Object, so no more doAnswer(...).when nonsense :)

I can put this into a pull request and add some tests if you like.

Happy mocking!

NullPointerException is thrown when stubbing a generic function using the lamda approach

here are examples to illustrate the issue ...

package bug.stubbing.lambda

import com.nhaarman.mockito_kotlin.mock
import com.nhaarman.mockito_kotlin.whenever
import com.winterbe.expekt.should
import org.junit.jupiter.api.Test

class LamdaStubbingIntialization { 

    // generic interface to illustrate stubbing issue
    interface GenericInterface<out T> {

        fun NonGeneric(): Double

        fun ASecondNonGeneric(): String

        fun Generic(): T
    }

    // stubbing a generic function through the lamda method fails
    // with a NullPointerException
    @Test
    fun FailedStubbingGenerics () {

        val mocked: GenericInterface<Int>

        try {
            mocked = mock {
                on { NonGeneric() }.thenReturn(-1.0)

                on { ASecondNonGeneric() }.thenReturn("multiple stubbing is not a problem")

                on { Generic() }.thenReturn(1)
            }
        } catch (ex: NullPointerException) {
            return@FailedStubbingGenerics
        }

        mocked.NonGeneric().should.be.equal(-1.0)

        mocked.ASecondNonGeneric().should.be.equal("multiple stubbing is not a problem")

        mocked.Generic().should.be.equal(1)

        // just signaling that it worked
        "unexpected pass".should.be.equal("means the mock worked")
    }

    // subbing a non-generic method of a generic interface is fine
    @Test
    fun PassingIncompleteStubbingGenerics () {

        val mocked: GenericInterface<Int> = mock {
            on { NonGeneric() }.thenReturn(-1.0)
        }

        mocked.NonGeneric().should.be.equal(-1.0)

        mocked.Generic().should.be.`null`
    }

    // stubbing a generic function through the non-lamda method works
    // so the problem is not stubbing a generic method
    @Test
    fun PassingStubbingGenerics () {

        val mocked: GenericInterface<Int> = mock()

        whenever(mocked.NonGeneric()).thenReturn(-1.0)
        whenever(mocked.Generic()).thenReturn(1)

        mocked.NonGeneric().should.be.equal(-1.0)

        mocked.Generic().should.be.equal(1)
    }
}

argThat() causes TypeCastException

interface HelloSrv {
    fun sayHello(to: String): String
}

class AnyTest {
    @Test fun `should create non-null values`() {
        mock<HelloSrv> {
            on { sayHello(argThat { this == "A" }) } doReturn "A"
            on { sayHello(argThat { this == "B" }) } doReturn "B" // <--- fails here
        }
    }
}

fails with

kotlin.TypeCastException: null cannot be cast to non-null type kotlin.String

	at kkk.command.AnyTest$should create non-null values$mock$1$1$$special$$inlined$argThat$1.matches(Mockito.kt:55)
	at org.mockito.internal.invocation.TypeSafeMatching.apply(TypeSafeMatching.java:24)
	at org.mockito.internal.invocation.MatcherApplicationStrategy.forEachMatcherAndArgument(MatcherApplicationStrategy.java:82)
	at org.mockito.internal.invocation.InvocationMatcher.argumentsMatch(InvocationMatcher.java:152)
	at org.mockito.internal.invocation.InvocationMatcher.matches(InvocationMatcher.java:81)
	at org.mockito.internal.stubbing.InvocationContainerImpl.findAnswerFor(InvocationContainerImpl.java:82)
	at org.mockito.internal.handler.MockHandlerImpl.handle(MockHandlerImpl.java:88)
	at org.mockito.internal.handler.NullResultGuardian.handle(NullResultGuardian.java:32)
	at org.mockito.internal.handler.InvocationNotifierHandler.handle(InvocationNotifierHandler.java:36)
	at org.mockito.internal.creation.bytebuddy.MockMethodInterceptor.doIntercept(MockMethodInterceptor.java:41)
	at org.mockito.internal.creation.bytebuddy.MockMethodInterceptor$DispatcherDefaultingToRealMethod.interceptAbstract(MockMethodInterceptor.java:120)
	at kkk.command.HelloSrv$MockitoMock$934695312.sayHello(Unknown Source)
	at kkk.command.AnyTest$should create non-null values$mock$1$2.invoke(AnyTest.kt:16)
	at kkk.command.AnyTest$should create non-null values$mock$1$2.invoke(AnyTest.kt:12)
	at com.nhaarman.mockito_kotlin.KStubbing.on(Mockito.kt:119)
	at kkk.command.AnyTest.should create non-null values(AnyTest.kt:16)

mockito-kotlin: 1.0.0
mockito: 2.2.28

eq and any failing with data classes

Looks like regardless of what data class eq and any has to instantiate, it always fails

java.lang.ClassCastException: org.mockito.Answers cannot be cast to org.mockito.stubbing.Answer

    at com.nhaarman.mockito_kotlin.CreateInstanceKt.uncheckedMock(CreateInstance.kt:162)
    at com.nhaarman.mockito_kotlin.CreateInstanceKt.createNullableInstance(CreateInstance.kt:151)
    at com.nhaarman.mockito_kotlin.CreateInstanceKt.newInstance(CreateInstance.kt:139)
    at com.nhaarman.mockito_kotlin.CreateInstanceKt.createInstance(CreateInstance.kt:60)

Reproduces always with version 0.4.0

Document Argument Captors in README

It would be nice to have an example of the syntax for using Argument Captors in Mockito-Kotlin. I got caught out because I used argumentCaptor.capture() instead of capture(argumentCaptor).

Here is an example of what it could be.

Argument Captors

These overcome the issue that Mockito ArgumentCaptor.capture() returns null, which results in an IllegalStateException in Kotlin.

Kotlin:

val argumentCaptor = argumentCaptor<String>()
myClass.doSomething()
verify(classToMock).sendString(capture(argumentCaptor))

I can raise this as a pull request if helpful. I would suggest adding it below the Argument Matchers section.

createInstance does not work with UUID

createInstance does not work with UUID, it tries to construct a UUID but the constructor throws an exception.

As a consequence any() and eq() does not work with UUID arguments

example:

val customer = Customer(id = UUID.randumUuid(), name = "Eugene Cuckoo")
whenever(customerDao.get( eq(customer.id) )).thenReturn(customer)

any() causes NullPointerException for Strings

Taking this example:

interface Api {
  fun search(query: String):Observable<...>
}
whenever(api.search(any()).thenReturn(empty())

It crashes with java.lang.IllegalArgumentException: Parameter specified as non-null is null for latest version of both this 0.12.1 and mockito 2.2.21

ArgForWhich alias for ArgThat

The following could be more intuitive:

- verify(mock).value = argThat { id == 1 }
+ verify(mock).value = argForWhich { id == 1 }

Can be implemented using:

inline fun <reified T : Any> argForWhich(noinline predicate: T.() -> Boolean) = argThat(predicate)

Android Test: ClassCastException: org.mockito.Answers cannot be cast to org.mockito.stubbing.Answer

I'm getting the following exception when I try to run a test that previously worked without mockito-kotlin:

java.lang.ClassCastException: org.mockito.Answers cannot be cast to org.mockito.stubbing.Answer
at com.nhaarman.mockito_kotlin.CreateInstanceKt.uncheckedMock(CreateInstance.kt:178)
at com.nhaarman.mockito_kotlin.CreateInstanceKt.createInstance(CreateInstance.kt:58)

I'm trying to isolate the code that is causing it.

Using version 0.5

Compatibility with PowerMock

Hi,

this lib looks really nice, thanks for sharing. I have a problem with PowerMock though which I am using to make final classes mockable. I do not want to open up all classes I want to mock just for testing.

Thing is powermock-api-mockito still uses Mockito 1.x which is not compatible with 2.x you are using. Is there a way to work around this (apart from forking your project and make it use Mockito 1.x)? Or is there a version of PowerMock wich is already using Mockito 2.x that I am just not able to find?

How do you treat final classes you want to mock?

Introduce anyOrNull / anything()

Mockito contains the following methods:

/** Matches <strong>anything</strong>, including nulls and varargs. */
public static <T> T any() 

/** Matches any object of given type, excluding nulls. */
public static <T> T any(Class<T> type)

In Mockito-Kotlin, there is just any(), which currently uses Mockito's any(Class<T>) and thus excluding nulls.
Introducing anyOrNull() to resolve to Mockito's any() can resolve issues like in #63.

An alternative would be to name this anything(), since it also includes varargs.
We should be wary of any confusion that may arise between using any() or anything() though.

capture throws InvalidUseOfMatchersException

I have class:

class ApiError: RuntimeException {

    constructor(cause: Throwable) : super(cause) {
        errorType = ErrorType.SYSTEM
        retrofitResponse = null
        validationErrors = emptyList()
    }

    constructor(retrofitError: RetrofitError) : super(retrofitError) {
        when (retrofitError.kind) {
            RetrofitError.Kind.HTTP -> errorType = ErrorType.SERVER
            else -> errorType = ErrorType.SYSTEM
        }

        retrofitResponse = retrofitError.response
        validationErrors = emptyList()
        parseApiResponse(retrofitError)
    }
    ....
}

Test looks like:

private val onApiError: Function1<ApiError, Unit> = mock()
private val apiErrorCaptor: ArgumentCaptor<ApiError> = argumentCaptor()

@Test
fun test() {
  verify(onApiError).invoke(capture(apiErrorCaptor)) //<--throws here
}

And got exception:

Caused by: org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Invalid use of argument matchers!
0 matchers expected, 1 recorded:
-> at com.vinted.data.rx.api.ApiObserverTest.testOnThrowedApiError(ApiObserverTest.kt:174)

This exception may occur if matchers are combined with raw values:
    //incorrect:
    someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
    //correct:
    someMethod(anyObject(), eq("String by matcher"));

For more info see javadoc for Matchers class.

    at java.lang.Throwable.<init>(Throwable.java:311)
    at java.lang.Exception.<init>(Exception.java:102)
    at java.lang.RuntimeException.<init>(RuntimeException.java:96)
    at com.vinted.data.rx.api.ApiError.<init>(ApiError.kt:30)
    ... 57 more

I checked, ApiError is constructed well using ApiError(Throwable) constructor. Something bad happens with matchers.

For my surprise, #22 fixes that issue. But I don't understand how.

Missing pom for v0.2.1

Hey Haarman, the latest version on bintray (0.2.1 as of 02/19/2016) doesn't have any pom files associated with it!! So gradle fails to pull in kotlin-reflect automatically

Also sources and javadoc jars are missing

Can you please fix this?

Thanks for a great library

mocking properties/fields

Unfortunately the following doesn't work:

open class ClassUnderTest ( val property:String )
val mock = mock<ClassUnderTest>()
whenever( mock.property ).thenReturn("value")
assert( mock.property == "value" )

because:

when() requires an argument which has to be 'a method call on a mock'

I think I understand the root cause of this but it still would be extremely helpful. I think while accessing variables directly is often considered a code smell in Java it is quite common for Kotlin.

Do you see any chance to be able to change that behaviour?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.