Giter VIP home page Giter VIP logo

mockk's Issues

Cannot objectMockk inline function

I tried to objectMockk an inline function of an object and it didn't seem to work.

I did sth like

`
@BeforeAll
fun beforeTests() {

    objectMockk(MockObj).mock()

    every { MockObj.getSth<Room>(1) } returns 1
}

`
and the getSth is simply like:

inline fun <reified T> getSth(): String { return (T::class.annotations.find { it is MongoDBCollection } as MongoDBCollection).name }

and it throws

=> io.mockk.MockKException: Missing calls inside every { ... } block

Is that mocking of inline function is not supported?

Thanks.

StackOverflowException with HashMap

I think this might be related to mockito/mockito#818 as maybe it was ported from the culprit over there.
I'm using 1.7.8 and actually in my case I'm not mocking a HashMap, but returning one from an every block

 val blob : CloudBlockBlob = mockk() // from azure-storage-java  
 val metadata : HashMap<String?,String?> = hashMapOf()
 every { blob.metadata } returns metadata

The StackOverflowException occurs when blob calls metadata. I don't know why HashMap is getting mocked though.
Honestly I don't know what is happening but that mockito bug looked too similar to ignore

Exception in thread "main" java.lang.StackOverflowError
at java.lang.Class.getDeclaredMethod(Class.java:2127)
at java.util.HashMap.get(HashMap.java:556)
at sun.reflect.Reflection.filterMethods(Reflection.java:291)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)

how to match varags?

I don't see how to create a mock match for a function accepting varargs. Is that supported? Thanks.

Bug: mocking java static method exception - o.mockk.MockKException: No other calls allowed in stdObjectAnswer than equals/hashCode/toString

sample

running that code leads to MockKException:

objc[29348]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/bin/java (0x1042c24c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x10434e4e0). One of the two will be used. Which one is undefined.
2018-03-21 12:17:18 DEBUG - [AbstractMockFactory] Creating spyk for MyLog4jExecutor name=#1, moreInterfaces=[]
2018-03-21 12:17:18 DEBUG - [AbstractMockFactory] Creating mockk for Thread name=#2, moreInterfaces=[]
2018-03-21 12:17:19 DEBUG - [AbstractMockFactory] Creating mockk for Runnable name=#3, moreInterfaces=[]
2018-03-21 12:17:19 DEBUG - [JvmStaticMockFactory] Creating static mockk for ThreadContext
2018-03-21 12:17:19 DEBUG - [MockKProxyMaker] Injecting handler to class org.apache.logging.log4j.ThreadContext for static methods

io.mockk.MockKException: No other calls allowed in stdObjectAnswer than equals/hashCode/toString

at io.mockk.impl.stub.MockKStub.stdObjectAnswer(MockKStub.kt:78)

part of my dependencies:
dependencies

Formatting: [Feature request] Better error report format

So, for a error report like this

Verification failed: call 2 of 2: class nz.salect.kotlinidiom.http.HttpKt.post(eq(http://localhost:8080/Login), eq({devid=, password=iAmNotAPassword!}), null())). Only one matching call to HttpKt(static HttpKt)/post(String, Map, Map) happened, but arguments are not matching:
[0]: argument: http://localhost:8080/Login, matcher: eq(http://localhost:8080/Login), result: +
[1]: argument: {devid=fake-dev-id, password=iAmNotAPassword!}, matcher: eq({devid=, password=iAmNotAPassword!}), result: -
[2]: argument: null, matcher: null(), result: +

Stack trace:
                                                       nz.salect.kotlinidiom.http.HttpKt.post              (http.kt:57)                               
                                                  nz.salect.kmoblib.services.AuthService.login             (AuthService.kt:40)                        
                                       nz.salect.kmoblib.AuthServiceTest$login_success$1.invoke            (AuthServiceTest.kt:165)                   
                                       nz.salect.kmoblib.AuthServiceTest$login_success$1.invoke            (AuthServiceTest.kt:17)                    
                                                       nz.salect.kmoblib.AuthServiceTest.mockHttpPost      (AuthServiceTest.kt:253)                   
                                                       nz.salect.kmoblib.AuthServiceTest.login_success     (AuthServiceTest.kt:164)                   
                                                    sun.reflect.NativeMethodAccessorImpl.invoke0           (NativeMethodAccessorImpl.java:-2)N        
                                                    sun.reflect.NativeMethodAccessorImpl.invoke            (NativeMethodAccessorImpl.java:62)         
                                                sun.reflect.DelegatingMethodAccessorImpl.invoke            (DelegatingMethodAccessorImpl.java:43)     
                                                                java.lang.reflect.Method.invoke            (Method.java:498)                          
                                               org.junit.runners.model.FrameworkMethod$1.runReflectiveCall (FrameworkMethod.java:50)                  
                                     org.junit.internal.runners.model.ReflectiveCallable.run               (ReflectiveCallable.java:12)      

It's detailed but still one more problem:

  1. Some lines are too long such that you need horizontal scroll in order to inspect them all.

I think we can't avoid horizontal scroll in every cases, but still I think mockk can deliever a better report like this:

Verification failed: call 2 of 2: 

class nz.salect.kotlinidiom.http.HttpKt.post(). 

Only one matching call to HttpKt(static HttpKt)/post(String, Map, Map) happened, but arguments are not matching:

[0]: 2nd argument mismatch: 
    expect: {devid=fake-dev-id, password=iAmNotAPassword!}, 
    actual: {devid=, password=iAmNotAPassword!}
    
Stack trace:
nz.salect.kotlinidiom.http.HttpKt.post                      (http.kt:57)                               
nz.salect.kmoblib.services.AuthService.login                (AuthService.kt:40)                        
nz.salect.kmoblib.AuthServiceTest$login_success$1.invoke    (AuthServiceTest.kt:165)                   
nz.salect.kmoblib.AuthServiceTest$login_success$1.invoke    (AuthServiceTest.kt:17)                    
nz.salect.kmoblib.AuthServiceTest.mockHttpPost              (AuthServiceTest.kt:253)                   
nz.salect.kmoblib.AuthServiceTest.login_success             (AuthServiceTest.kt:164)   

libattach.dylib loaded twice

Tests run: 22, Failures: 0, Errors: 10, Skipped: 0, Time elapsed: 0.213 s <<< FAILURE! - in hm.binkley.labs.skratch.knapsack.ValueSetMockTest
shouldStartZeroSized()  Time elapsed: 0.013 s  <<< ERROR!
java.lang.ExceptionInInitializerError
	at hm.binkley.labs.skratch.knapsack.LayersMockTest.<init>(LayersMockTest.kt:57)
Caused by: java.lang.IllegalStateException: Error during attachment using: io.mockk.shadowed.bytebuddy.agent.ByteBuddyAgent$AttachmentProvider$Compound@2c3c9e65
	at hm.binkley.labs.skratch.knapsack.LayersMockTest.<init>(LayersMockTest.kt:57)
Caused by: java.lang.reflect.InvocationTargetException
	at hm.binkley.labs.skratch.knapsack.LayersMockTest.<init>(LayersMockTest.kt:57)
Caused by: java.lang.UnsatisfiedLinkError: Native Library /Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/jre/lib/libattach.dylib already loaded in another classloader
	at hm.binkley.labs.skratch.knapsack.LayersMockTest.<init>(LayersMockTest.kt:57)

any() matcher for java Class parameter fails with IllegalAccessError

if I have a method parameter that is of type java.lang.Class<?> like:

public boolean isRegistered(Class<?> componentClass);

or in Kotlin:

fun gimmeJavaClass(klass: Class<*>): Boolean = true

then the any() matcher causes a java.lang.Class exception:

java.lang.IllegalAccessError: java.lang.Class

	at sun.reflect.GeneratedSerializationConstructorAccessor12.newInstance(Unknown Source)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:48)
	at io.mockk.proxy.MockKProxyMaker.newEmptyInstance(MockKProxyMaker.java:230)
	at io.mockk.proxy.MockKProxyMaker.instance(MockKProxyMaker.java:63)
	at io.mockk.impl.instantiation.JvmInstantiator$instantiate$2.invoke(JvmInstantiator.kt:16)
	at io.mockk.impl.instantiation.AbstractInstantiator.instantiateViaInstanceFactoryRegistry(AbstractInstantiator.kt:17)
	at io.mockk.impl.instantiation.JvmInstantiator.instantiate(JvmInstantiator.kt:15)
	at io.mockk.impl.recording.states.RecordingState$matcher$signatureValue$1$1.invoke(RecordingState.kt:46)
	at io.mockk.impl.instantiation.JvmAnyValueGenerator$anyValue$1.invoke(JvmAnyValueGenerator.kt:24)
	at io.mockk.impl.instantiation.AnyValueGenerator.anyValue(AnyValueGenerator.kt:27)
	at io.mockk.impl.instantiation.JvmAnyValueGenerator.anyValue(JvmAnyValueGenerator.kt:20)
	at io.mockk.impl.recording.states.RecordingState$matcher$signatureValue$1.invoke(RecordingState.kt:45)
	at io.mockk.impl.recording.JvmSignatureValueGenerator.signatureValue(JvmSignatureValueGenerator.kt:20)
	at io.mockk.impl.recording.states.RecordingState.matcher(RecordingState.kt:44)
	at io.mockk.impl.recording.CommonCallRecorder.matcher(CommonCallRecorder.kt:47)
	at io.mockk.MockKTestSuite$1$11$1.invoke(MockKTestSuite.kt:607)
	at io.mockk.MockKTestSuite$1$11$1.invoke(MockKTestSuite.kt:10)
	at io.mockk.impl.eval.RecordedBlockEvaluator$record$block$1.invoke(RecordedBlockEvaluator.kt:22)
	at io.mockk.impl.recording.JvmAutoHinter.autoHint(JvmAutoHinter.kt:23)
	at io.mockk.impl.eval.RecordedBlockEvaluator.record(RecordedBlockEvaluator.kt:31)
	at io.mockk.impl.eval.EveryBlockEvaluator.every(EveryBlockEvaluator.kt:25)

Here is a test case:

  1. Modify your io.mockk.MockCls class in CommonCallRecorderTest to add
fun gimmeJavaClass(klass: Class<*>): Boolean = true
  1. Add this test. It will fail:
"any class" {
        every { mock.gimmeJavaClass(any()) }.returns(false)
        assertEquals(false, mock.gimmeJavaClass(Long::class.java))
    }

Is there a way to mock a property value?

When I use the following code to mock a property value, I get nulls.

    private val view = mockk<LoginView>(relaxed = true)
    private val auth = mockk<AuthenticationManager>(relaxed = true)
    private val presenter = LoginPresenter(auth)

    @Test
    fun onSignInClicked_loginInvalid_showError(){
        every { view.login } returns "dd"
        every { view.password } returns "password"

        presenter.onSignInClicked()
...

Is there a workaround for this problem or am I missing something?

Feature Request: Return sensible default Answers for Every

Currently Mockk is designed to throw an exception if every is not called with an accompanying Answer. This means that every mock interaction must be accounted for when writing tests. It would be convenient if every assumed a sensible default Answer.

Consider the following code:
Production:

class LocalBusAware(val eventBus: EventBus) {
 fun open() {
   if (!eventBus.isRegistered(this)) {
        eventBus.register(this)
   }
 }
}

Test (current state):

    @Test
    fun openRegistersWithTheBus() {
        val eventBus = mockk<EventBus>()
        val subject = LocalBusAware(eventBus)
        every { eventBus.isRegistered(subject) } returns false
        every {eventBus.register(subject)} returns Unit
        subject.open()

        verify {eventBus.register(subject)}
    }

In this example isRegistered() and register() must both have defined every calls with specific returns values. In more complex scenarios this can be extremely cumbersome, as every mock action must be accounted for.

A more preferable test might be something like this:

    @Test
    fun openRegistersWithTheBus() {
        val eventBus = mockk<EventBus>() 
        val subject = LocalBusAware(eventBus)
        subject.open()

        verify {eventBus.register(subject)}
    }

In this example isRegistered() returns false by default, and does not need to be explicitly defined, and register() returns Unit (and it is part of the verify sequence), so it does not need to be explicitly defined either.

Our tests can be much more focused, only requiring interactions that we care about to execute our scenario. This would also be more in line with what frameworks such as Mockito do, and I think it would help drive adoption of Mockk from those frameworks.

Thoughts?

Fix typos

dsl/common/src/main/kotlin/io/mockk/Matchers.kt comparision -> comparison
agent/src/main/java/io/mockk/proxy/MockKInstrumentation.java tranform -> transform

Constructor: spyk doesn't register calls from constructor

Spy verification doesn't work for methods called from constructor:

class TestClass {
  init { test() }
  fun test() {}
}
...
val spyed = spyk(TestClass())
...
verify { spyed.test() }

I'm kinda novice at testing but I do understand one could create another constructor for testing purpose without some kind of setup method call. I just wonder, is this feature out of scope or planned for future?

Recieve Instantiation Error on Argument-Matching Arrays

I could not see in the documentation which I find straightforward any mention of not supporting Array argument matching.

With that in mind could I asking whether this is a Mockk bug, or what is being done wrong in this code.

Stacktrac

java.lang.InstantiationError: [Lorg.springframework.jdbc.core.namedparam.SqlParameterSource;
	at sun.reflect.GeneratedSerializationConstructorAccessor19.newInstance(Unknown Source)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at io.mockk.shadowed.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:48)
	at io.mockk.proxy.MockKProxyMaker.newEmptyInstance(MockKProxyMaker.java:184)
	at io.mockk.proxy.MockKProxyMaker.instance(MockKProxyMaker.java:52)
	at io.mockk.impl.InstantiatorImpl.instantiate(Instantiator.kt:53)
	at io.mockk.impl.InstantiatorImpl.signatureValue(Instantiator.kt:109)
	at io.mockk.impl.CallRecorderImpl.matcher(CallRecording.kt:97)

What I am trying to mock:
org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.batchUpdate(String, Array<SqlParameterSource>)

How I am trying to mock it:

        every {
            localDb.batchUpdate(
                match{ sql: String ->
                    sql == PaymentDao.Companion.PAYMENT_INSERT_SQL_STMT
                },
                any<Array<SqlParameterSource>>()
            )
         } returns intArrayOf(1)

staticMockk to Mock Companion Object?

Hello,
Can I use staticMockk function to mock a companion object?
I got something like
class StreamingStore private constructor() {

companion object {
private val store: ReadOnlyKeyValueStore<String, String>//kafka readOnlyStore

get(key:UUID): DomainObject{
val message = store.get(key.toString())
//logic
return DomainObject
}
}

On my test I tried
staticMockk("package.StreamingStore").use {
every {
get(uuid.toString())
} returns DomainObject(UUID.randomUUID())
}
but it's not working

java.lang.AssertionError: Verification failed: call 2 of 2

My code is as follows:

[some init code...]
every { myMockedHelper.getSomething(FLAG, "Some string", mockContext, somePath) } returns mockAsyncTask
every { myMockedHelper.executeAsyncTaskParallel(mockAsyncTask) } just Runs

MyConnector.getHelperGraph().getOtherHelper().showStuffOnUi(FLAG, "Some string", mockContext)
verify { MyConnector.getHelperGraph().getOtherHelper().showStuffOnUi(FLAG, "Some string", mockContext)

When running the test, it fails with the following error.

java.lang.AssertionError: Verification failed: call 2 of 2: MyHelper(#2).executeAsyncTaskParallel(eq(AsyncTask(child of #2)))). Only one matching call to MyHelper(#2)/executeAsyncTaskParallel(AsyncTask) happened, but arguments are not matching:
[0]: argument: AsyncTask(#3), matcher: eq(AsyncTask(child of #2)), result: -

How can I solve this issue? What is causing this?

spykk complaining it couldn’t initialize

@yannickvg let's move this to another open thread.

So your report:

Was trying out the spyk() but with less success. I also use dagger, so in
the class i want to spy i have a primary constructor with some dependencies.
So obviously it complained it couldn’t initialize.

I tried doing what i would do in java and made 2 constructors, one with
dependencies, one without and created lateinit var fields for the
dependencies, but then i get errors that the properties have not been
initialized.

So still figuring out how to use the spy with mandatory 

Can you send exception dumps of those complains?

Broken JDK7 compatibility

Mockk 1.7.9 (and all other versions I guess) is currently unable to run under JDK7 due to forEach lambda in JvmAutoHinter for example.

Bug: Mocking kotlin objects which has variables initialization

Ex:

      object Real {
        var filePath = getExternalStorage("dir").path
      }

Now when trying to mock this using, objectMockk(Real).mock(), I get,

       java.lang.ExceptionInInitializerError,
      Caused by: java.lang.IllegalStateException: getExternalStorage("dir") must not be null

for trying to access external storage. Is there any way to mock these kind of objects?

Unable to mock Enum responses

I'm having some trouble mocking enum responses, for example, if i have the following ugly kotlin class.
Using Kotlin 1.2.20 and mockk 1.7

class KotlinClassWithEnumMember {
    var type: EnumType? = null

    enum class EnumType {
        ONE, TWO, THREE
    }
}

And the following test code

@Test
fun `Test mocking enum member in class`() {
    val mockedClass = mockk<ClassWithEnumMember>()
    every { mockedClass.type } returns ClassWithEnumMember.EnumType.ONE
    assertEquals(ClassWithEnumMember.EnumType.ONE, mockedClass.type, "Enum returned does not match mocked response")
}

It will throw the following error:


kotlin.reflect.jvm.internal.KotlinReflectionInternalError: Reflection on built-in Kotlin types is not yet fully supported. No metadata found for public final val name: kotlin.String defined in kotlin.Enum[DeserializedPropertyDescriptor@31aa3ca5]

	at kotlin.reflect.jvm.internal.RuntimeTypeMapper.mapPropertySignature(RuntimeTypeMapper.kt:212)
	at kotlin.reflect.jvm.internal.KPropertyImpl.<init>(KPropertyImpl.kt:49)
	at kotlin.reflect.jvm.internal.KProperty1Impl.<init>(KProperty1Impl.kt:27)
	at kotlin.reflect.jvm.internal.KDeclarationContainerImpl.createProperty(KDeclarationContainerImpl.kt:91)
	at kotlin.reflect.jvm.internal.KDeclarationContainerImpl.access$createProperty(KDeclarationContainerImpl.kt:31)
	at kotlin.reflect.jvm.internal.KDeclarationContainerImpl$getMembers$visitor$1.visitPropertyDescriptor(KDeclarationContainerImpl.kt:53)
	at kotlin.reflect.jvm.internal.KDeclarationContainerImpl$getMembers$visitor$1.visitPropertyDescriptor(KDeclarationContainerImpl.kt:51)
	at kotlin.reflect.jvm.internal.impl.descriptors.impl.PropertyDescriptorImpl.accept(PropertyDescriptorImpl.java:467)
	at kotlin.reflect.jvm.internal.KDeclarationContainerImpl.getMembers(KDeclarationContainerImpl.kt:66)
	at kotlin.reflect.jvm.internal.KClassImpl$Data$declaredNonStaticMembers$2.invoke(KClassImpl.kt:152)
	at kotlin.reflect.jvm.internal.KClassImpl$Data$declaredNonStaticMembers$2.invoke(KClassImpl.kt:43)
	at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:93)
	at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:32)
	at kotlin.reflect.jvm.internal.KClassImpl$Data.getDeclaredNonStaticMembers(KClassImpl.kt)
	at kotlin.reflect.jvm.internal.KClassImpl$Data$allNonStaticMembers$2.invoke(KClassImpl.kt:161)
	at kotlin.reflect.jvm.internal.KClassImpl$Data$allNonStaticMembers$2.invoke(KClassImpl.kt:43)
	at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:93)
	at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:32)
	at kotlin.reflect.jvm.internal.KClassImpl$Data.getAllNonStaticMembers(KClassImpl.kt)
	at kotlin.reflect.jvm.internal.KClassImpl$Data$allMembers$2.invoke(KClassImpl.kt:167)
	at kotlin.reflect.jvm.internal.KClassImpl$Data$allMembers$2.invoke(KClassImpl.kt:43)
	at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:93)
	at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:32)
	at kotlin.reflect.jvm.internal.KClassImpl$Data.getAllMembers(KClassImpl.kt)
	at kotlin.reflect.jvm.internal.KClassImpl.getMembers(KClassImpl.kt:182)
	at kotlin.reflect.full.KClasses.getFunctions(KClasses.kt:90)
	at kotlin.reflect.jvm.ReflectJvmMapping.getKotlinFunction(ReflectJvmMapping.kt:137)
	at io.mockk.impl.instantiation.JvmMockFactoryHelper.varArgPosition(JvmMockFactoryHelper.kt:53)
	at io.mockk.impl.instantiation.JvmMockFactoryHelper.toDescription(JvmMockFactoryHelper.kt:69)
	at io.mockk.impl.instantiation.JvmMockFactoryHelper$mockHandler$1.invoke(JvmMockFactoryHelper.kt:16)
	at io.mockk.impl.instantiation.JvmMockFactoryHelper$mockHandler$1.invoke(JvmMockFactoryHelper.kt:12)
	at io.mockk.impl.instantiation.JvmMockFactoryKt$sam$MockKInvocationHandler$4dff1f07.invocation(JvmMockFactory.kt)
	at io.mockk.proxy.MockKCallProxy.call(MockKCallProxy.java:24)
	at java.lang.Enum.hashCode(Enum.java:152)
	at io.mockk.RecordedCall.hashCode(API.kt)
	at java.util.HashMap.hash(HashMap.java:339)
	at java.util.HashMap.put(HashMap.java:612)
	at io.mockk.impl.recording.PermanentMocker.describeCallTree(PermanentMocker.kt:98)
	at io.mockk.impl.recording.PermanentMocker.access$describeCallTree(PermanentMocker.kt:11)
	at io.mockk.impl.recording.PermanentMocker$mock$callTree$1.invoke(PermanentMocker.kt:28)
	at io.mockk.impl.recording.PermanentMocker$mock$callTree$1.invoke(PermanentMocker.kt:11)
	at io.mockk.impl.recording.CommonCallRecorder.safeExec(CommonCallRecorder.kt:66)
	at io.mockk.impl.log.SafeLog.exec(SafeLog.kt:10)
	at io.mockk.impl.recording.PermanentMocker.mock(PermanentMocker.kt:28)
	at io.mockk.impl.recording.states.RecordingState.mockPermanently(RecordingState.kt:85)
	at io.mockk.impl.recording.states.RecordingState.round(RecordingState.kt:30)
	at io.mockk.impl.recording.CommonCallRecorder.round(CommonCallRecorder.kt:45)
	at io.mockk.impl.eval.RecordedBlockEvaluator.record(RecordedBlockEvaluator.kt:47)
	at io.mockk.impl.eval.EveryBlockEvaluator.every(EveryBlockEvaluator.kt:25)
	at KotlinClassWithEnumMemberTest.Test mocking enum member in lateinit class(KotlinClassWithEnumMemberTest.kt:63)
	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.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
	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: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)

Furthermore, any other every calls on the same class (different mock instance and different field) will throw a


io.mockk.MockKException: Bad recording sequence. State: StubbingState

	at io.mockk.impl.recording.states.CallRecordingState.cancelAndThrowBadRecordingState(CallRecordingState.kt:30)
	at io.mockk.impl.recording.states.CallRecordingState.startStubbing(CallRecordingState.kt:13)
	at io.mockk.impl.recording.CommonCallRecorder.startStubbing(CommonCallRecorder.kt:32)
	at io.mockk.impl.eval.EveryBlockEvaluator.every(EveryBlockEvaluator.kt:20)
	at KotlinClassWithEnumMemberTest.Test mocking string member in lateinit class(KotlinClassWithEnumMemberTest.kt:69)
	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.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
	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: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)

There is a project with the minimal unittests set up over here: https://github.com/sleepkever/mockk-enumtest

Is there something i'm doing wrong here?

spyk broken for class hierarchies

Thanks, mockk is looking really promising!
Howver, it seems like there are a few issues with spy when the object inherits from a base class.
Some examples:

the 'logger' fields can be anything, but it is a pretty common pattern, and one where you may have private final fields with the same name in a class and its superclass.

        open class BaseTest(val someReference:String) {
            private var logger: org.slf4j.Logger = LoggerFactory.getLogger(BaseTest::class.java)
            open fun doLog() {
                logger.info("Base $someReference")
            }
        }

        class SpyTest() : BaseTest("A spy"){
            private var logger: org.slf4j.Logger = LoggerFactory.getLogger(SpyTest::class.java)
            override fun doLog() {
                logger.info("spyTest")
            }
        }

        val spyObj = spyk<BaseTest>(SpyTest()) // this breaks.
//        val spyObj = spyk<SpyTest>(SpyTest()) // uncomment this as a semi-workaround
        every {
            spyObj.doLog()
        } just Runs.apply{println("Intercepted")}
        // but superclass fields are not set correctly, so this fails too:
        assert(spyObj.someReference != null)
        spyObj.doLog()

Verify failing with arguments not matching

Relevant StackOverflow

I've noticed that sometimes verify fails with "... call to ... happened, but arguments are not matching"

Here is a sample test that shows verify failing:

class TestStuff {

    val stuff = "1"

    @RelaxedMockK
    lateinit var testService: TestService

    @RelaxedMockK
    lateinit var testInterface: TestInterface

    @Before
    fun setup() {
        MockKAnnotations.init(this)

        every { testInterface.testStuff } returns stuff
    }

    @Test
    fun testStuffCalled() {
        testService.testStuff(testInterface.testStuff)

        verify { testService.testStuff(testInterface.testStuff) }
    }
}

interface TestInterface {
    val testStuff: String
}

class TestService {

    fun testStuff(stuff: String) {
    }
}

Not able to mock for return type as Arrow#Either

I am trying mock a method call which returns of Either type of Arrow Library. But i am getting below exception when writing the Mock behaviour
code : every { /*somemethod call*/ }.returns(Either.left(/*Some object*/)

Exception
kotlin.reflect.jvm.internal.KotlinReflectionInternalError: Incorrect resolution sequence for Java field public final val isLeft: kotlin.Boolean defined in arrow.core.Either$ByteBuddy$0FhSn1dn[JavaPropertyDescriptor@3c49fab6] (source = null)
Is this something to be fixed in the library or its not at all support shield classes ?

Show stacktrace of undesirable call in `verify` error message

Currently, if verify block throws an assert because you have undesired mock method call you cannot detect who called this method, so the only option to debug this case.

Currently I see something like:
java.lang.AssertionError: Verification failed: call 1 of 1: SomeClass(#10).someMethid()). 2 matching calls found, but needs at least 0 and at most 1 calls

But would be very good to have something like:

java.lang.AssertionError: Verification failed: call 1 of 1: SomeClass(#10).someMethid()). 2 matching calls found, but needs at least 0 and at most 1 calls
Call 1: SomeOtherClass:123 // Class with line number
Call 2: OneMoreClass:24

Bug: Mocking varargs

In Mockito there is anyVararg() but mockk does not have this.
Consider the following example:

interface Foo {
   fun foo(vararg args: String, otherArg: String)
   fun foo(args: List<String>, otherArg: String)
}

@Test
fun varargTest() {
   val mock = mockk<Foo>()
   // this works as expected, matching the List<String> version
   every { mock.foo(args = any<List<String>>(), otherArg = any()) } just Runs

   // this does not work, compiles but fails at runtime with:
   // io.mockk.MockKException: Failed matching mocking signature for
   // Foo(#1).foo([529c407ddf5619f7], -4522a650db14c274)
   // left matchers: [any()]
   every { mock.foo(args = *arrayOf(any()), otherArg = any()) } just Runs
}

Is there another way to mock the vararg version of foo?

Mocking data classes causes MockKException

I have a number of data classes and I cannot seem to mock them as they do not have a non arg constructor. Kotlin does not allow this. If I convert it to a normal class then it seems to be able to mock the class.

Im using JUnit 5 with @ExtendWith(MockKExtension::class)

io.mockk.MockKException: No matching constructors found:
constructor(entity : com.google.cloud.datastore.Entity = )
constructor(id : java.util.UUID = , firstName : kotlin.String = , lastName : kotlin.String = , email : kotlin.String = , schoolId : java.util.UUID = , classId : java.util.UUID = , password : kotlin.String = )

at io.mockk.impl.annotations.MockInjector.constructorInjection(MockInjector.kt:20)
at io.mockk.impl.annotations.JvmMockInitializer.doInjection(JvmMockInitializer.kt:62)
at io.mockk.impl.annotations.JvmMockInitializer.initMock(JvmMockInitializer.kt:40)
at io.mockk.impl.annotations.JvmMockInitializer.initAnnotatedMocks(JvmMockInitializer.kt:17)
at io.mockk.junit5.MockKExtension.postProcessTestInstance(MockKExtension.kt:93)
at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.lambda$invokeTestInstancePostProcessors$3(ClassTestDescriptor.java:215)
at org.junit.jupiter.engine.descriptor.JupiterTestDescriptor.executeAndMaskThrowable(JupiterTestDescriptor.java:141)
at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.lambda$invokeTestInstancePostProcessors$4(ClassTestDescriptor.java:215)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:312)
at java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:743)
at java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:742)
at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.invokeTestInstancePostProcessors(ClassTestDescriptor.java:214)
at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.instantiateAndPostProcessTestInstance(ClassTestDescriptor.java:196)
at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.lambda$testInstanceProvider$0(ClassTestDescriptor.java:185)
at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.lambda$testInstanceProvider$1(ClassTestDescriptor.java:189)
at java.util.Optional.orElseGet(Optional.java:267)
at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.lambda$testInstanceProvider$2(ClassTestDescriptor.java:188)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:81)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:58)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.prepare(HierarchicalTestExecutor.java:89)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:74)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$2(HierarchicalTestExecutor.java:120)
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
at java.util.Iterator.forEachRemaining(Iterator.java:116)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:120)
at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$2(HierarchicalTestExecutor.java:120)
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
at java.util.Iterator.forEachRemaining(Iterator.java:116)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:120)
at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:55)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:43)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:170)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:154)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:90)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:65)
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)

List verification failure

In the last line it will fail, but it shouldn't, as much I understand:

@Test fun list() {
        val f: (List<Int>) -> Unit = mockk {
            every { [email protected](any()) } just Runs
        }
        val list = listOf(1, 2, 3, 4, 5)
        val listClone = list.toList()
        f(list)
        Assert.assertEquals(list, listClone)
        verify { f(listClone) }
}

Turn off logging

Thanks for this project. Really great stuff!!

I was wondering whether it is possible to turn off logging? I am getting all kinds of output such as INFO messages in the console.

Thanks in advance

Add optional argument to function mockk to configure created mock

Now we have a lot of cases when we create mock and want to configure it on the place (usually set every for methods).
To do that now we use apply:

val someMock: SomeClass = mockk().apply {
    every { someMethod() } returns "Foo"
}

Would be helpful to have mock configuration lambda with receiver as the latest argument in mockk:
Now

inline fun <reified T : Any> mockk(
    name: String? = null,
    relaxed: Boolean = false,
    vararg moreInterfaces: KClass<*>
): T

After:

inline fun <reified T : Any> mockk(
        name: String? = null,
        relaxed: Boolean = false,
        vararg moreInterfaces: KClass<*>,
        block: T.() -> Unit = {} // Cannot be null, but we can reuse cached instance to avoid calling empty block
): T

so now you can use mockk this way:

val someMock: SomeClass = mockk {
    every { someMethod() } returns "Foo"
}

Also works with all other optional arguments

Static: Mock Module wide Extension Method from Different Module

Hi,

Let's say I have an Module wide free Function in one Module:

fun getValue(): Int {
    return 1
}

With a package Path: com.company.module1
And File name FreeFunctions.kt

And I want to Mock the Response from a Test Class in another Module.
With package Path: com.company.module2

Is this possible?
I tried:

staticMockk("com.company.module1.FreeFunctions.kt").use {
    every{ getValue() } returns 1
}

But the mock is not used. Any help appreciated!

Bug: StackOverflowError using spyk but not spying with mockito in Robolectric

Hi! First things first, thanks for the great work done.

I have a test which looks like this and it's working properly:

val activity = Robolectric.buildActivity(MainActivity::class.java).get()
val testActivity = Mockito.spy(activity)

testActivity.onCreate(null)

Mockito.verify(testActivity).setContentView(R.layout.activity_main)

How could I achieve the same with Mockk?

I have tried the following but I`m getting a StackOverflowError:

val activity = Robolectric.buildActivity(MainActivity::class.java).get()
val testActivity = spyk(activity)

testActivity.onCreate(null)

verify { testActivity.setContentView(R.layout.activity_main) }

Here the full stack trace (mockk version: 1.7.10):
https://gist.github.com/PublioDev/53c372a8fe69989a9b8f36b9b380c733

Bug: callOriginal() for default interface methods is not working

import io.mockk.every
import io.mockk.mockk
import io.mockk.spyk
import io.mockk.verify
import javax.xml.crypto.Data

data class ItemData(val id: Int)

interface Database {
    fun insertItems(items: List<ItemData>)
    fun deleteItems(items: List<ItemData>)
    fun runTransaction(alsoDelete: Boolean) {
        insertItems(listOf(ItemData(id = 1), ItemData(id = 2), ItemData(id = 3)))
        if (alsoDelete)
            deleteItems(listOf(ItemData(id = 4), ItemData(id = 5), ItemData(id = 6)))
    }
}


fun main(args: Array<String>) {
    val x = mockk<Database>()
    every { x.runTransaction(any()) } answers { callOriginal() }
    x.runTransaction(alsoDelete = true)
    verify { x.insertItems(listOf(ItemData(id = 1), ItemData(id = 2), ItemData(id = 3))) }
}

Should work

Bug: Mocking Lambda NullpointerException in Robolectric

When a class receives a lambda as a parameter, one might want to mock the received lambda, so it may be possible to verify its behaviour.

But, unfortunately, there's a NullPointerException when trying to mock a lambda:

 class LambdaClass(val lambda: (Int) -> Unit) {
        
        fun doStuff() {
            lambda(5)
        }
    }
    
    @Test
    fun testLambda() {
        val mockedLambda: (Int) -> Unit = mockk()
        val klass = LambdaClass(mockedLambda)
        klass.doStuff()
        
        verify { mockedLambda(5) }
    }

java.lang.NullPointerException
at io.mockk.proxy.MockKProxyInterceptor.intercept(MockKProxyInterceptor.java:16)
at kotlin.jvm.functions.Function1$ByteBuddy$5kfph9ys$ByteBuddy$wGXaV9Md.invoke(Unknown Source)
at my.package.Playground$LambdaClass.doStuff(Playground.kt:26)
at my.package.Playground.testLambda(Playground.kt:34)

equivalent of verifyNoMoreInteractions() ?

Hi all, I'm converting many tests in Kotlin + Mockk and I wonder how to run the equivalent of verifyNoMoreInteractions() from Mockito?

I can do verifyZeroInteractions() with verify(exactly=0) { .. } but for the other one I don't see a way.

Any help ;) ?

Dex issue with mockk for instrumentation test environment

I have a use case with using Kotlin classes in my UI tests. To mock them I have opted with mockk, because of the class finalization that mockk gracefully solves.

The problem is that it lacks some setup. I am facing dex issue. I do suspect that it is connected to the same problem mockito library had. It was solved by LinkedIn and their dexmaker solution. Is there any way we can run mockk on the emulator or real device dex environment?

Caused by: java.lang.ClassNotFoundException: Didn't find class "java.lang.instrument.ClassFileTransformer" on path: DexPathList[[zip file "/system/framework/android.test.runner.jar", zip file "/system/framework/android.test.mock.jar"],nativeLibraryDirectories=[/data/app/my.app.test-35h1VdSJ4oyoucfymSsugg==/lib/arm64, /data/app/my.app.staging.debug-7njk-OasH4iMH8Dkfhr-4A==/lib/arm64, /data/app/my.app.test-35h1VdSJ4oyoucfymSsugg==/base.apk!/lib/arm64-v8a, /data/app/my.app.staging.debug-7njk-OasH4iMH8Dkfhr-4A==/base.apk!/lib/arm64-v8a, /system/lib64, /vendor/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:125)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)

Feature: Support Kotlin/Native in MockK

For multiplatform projects it would be really nice if MockK would support Kotlin/Native as well. If some missing functionality on K/N side is needed, please let us know, and we will add it.

Class cast exception while mocking MutableList

Hello,

I'm having problems to mock a mutable list.

My use case is that I simple want a mock for a mutableList and specify what list to return in the mutableList.toList() call. But when I try to assert the result, I get a class cast exception:

java.lang.ClassCastException: java.util.Collections$SingletonList cannot be cast to java.lang.Integer

Here a simple code that shows the problem:

class Test () {

    val mutableList = mockk<MutableList<String>>()

    @Test
    fun test() {

        val expectedList = listOf("1")
        every { mutableList.toList() } returns expectedList

        val list = mutableList.toList()
        Assert.assertEquals(expectedList, list)

    }
}

java.util.ServiceConfigurationError while mocking classes instance methods for Kotlin 1.2.21

Hello,

I am reproducing the following error when I am trying to mock the android.database.Cursor.

java.util.ServiceConfigurationError: kotlin.reflect.jvm.internal.impl.resolve.ExternalOverridabilityCondition: Provider kotlin.reflect.jvm.internal.impl.load.java.JavaIncompatibilityRulesOverridabilityCondition could not be instantiated
class SomeTest {
    val c = mockk<Cursor>()

    @Test
    fun name() {
        every { c.getColumnIndex(any()) } returns 1
    }
}

Full stacktrace:

com.intellij.rt.execution.application.AppMainV2 com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 com.showmax.lib.download.downloader.SomeTesrt

java.util.ServiceConfigurationError: kotlin.reflect.jvm.internal.impl.resolve.ExternalOverridabilityCondition: Provider kotlin.reflect.jvm.internal.impl.load.java.JavaIncompatibilityRulesOverridabilityCondition could not be instantiated

	at java.util.ServiceLoader.fail(ServiceLoader.java:232)
	at java.util.ServiceLoader.access$100(ServiceLoader.java:185)
	at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:384)
	at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
	at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
	at kotlin.collections.CollectionsKt___CollectionsKt.toCollection(_Collections.kt:1042)
	at kotlin.collections.CollectionsKt___CollectionsKt.toMutableList(_Collections.kt:1075)
	at kotlin.collections.CollectionsKt___CollectionsKt.toList(_Collections.kt:1066)
	at kotlin.reflect.jvm.internal.impl.resolve.OverridingUtil.<clinit>(OverridingUtil.java:45)
	at kotlin.reflect.jvm.internal.impl.load.java.components.DescriptorResolverUtils.resolveOverrides(DescriptorResolverUtils.java:67)
	at kotlin.reflect.jvm.internal.impl.load.java.components.DescriptorResolverUtils.resolveOverridesForNonStaticMembers(DescriptorResolverUtils.java:45)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaClassMemberScope.addFunctionFromSupertypes(LazyJavaClassMemberScope.kt:281)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaClassMemberScope.computeNonDeclaredFunctions(LazyJavaClassMemberScope.kt:245)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaScope$functions$1.invoke(LazyJavaScope.kt:89)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaScope$functions$1.invoke(LazyJavaScope.kt:51)
	at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$MapBasedMemoizedFunction.invoke(LockBasedStorageManager.java:402)
	at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$MapBasedMemoizedFunctionToNotNull.invoke(LockBasedStorageManager.java:470)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaScope.getContributedFunctions(LazyJavaScope.kt:224)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaClassMemberScope.getContributedFunctions(LazyJavaClassMemberScope.kt:654)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaClassMemberScope.getFunctionsFromSupertypes(LazyJavaClassMemberScope.kt:370)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaClassMemberScope.computeNonDeclaredFunctions(LazyJavaClassMemberScope.kt:241)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaScope$functions$1.invoke(LazyJavaScope.kt:89)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaScope$functions$1.invoke(LazyJavaScope.kt:51)
	at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$MapBasedMemoizedFunction.invoke(LockBasedStorageManager.java:402)
	at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$MapBasedMemoizedFunctionToNotNull.invoke(LockBasedStorageManager.java:470)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaScope.getContributedFunctions(LazyJavaScope.kt:224)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaClassMemberScope.getContributedFunctions(LazyJavaClassMemberScope.kt:654)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaScope.computeDescriptors(LazyJavaScope.kt:326)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaScope$allDescriptors$1.invoke(LazyJavaScope.kt:57)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaScope$allDescriptors$1.invoke(LazyJavaScope.kt:51)
	at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedLazyValue.invoke(LockBasedStorageManager.java:323)
	at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedNotNullLazyValue.invoke(LockBasedStorageManager.java:364)
	at kotlin.reflect.jvm.internal.impl.load.java.lazy.descriptors.LazyJavaScope.getContributedDescriptors(LazyJavaScope.kt:305)
	at kotlin.reflect.jvm.internal.impl.resolve.scopes.ResolutionScope$DefaultImpls.getContributedDescriptors$default(ResolutionScope.kt:37)
	at kotlin.reflect.jvm.internal.KDeclarationContainerImpl.getMembers(KDeclarationContainerImpl.kt:61)
	at kotlin.reflect.jvm.internal.KClassImpl$Data$declaredNonStaticMembers$2.invoke(KClassImpl.kt:139)
	at kotlin.reflect.jvm.internal.KClassImpl$Data$declaredNonStaticMembers$2.invoke(KClassImpl.kt:39)
	at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:93)
	at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:32)
	at kotlin.reflect.jvm.internal.KClassImpl$Data.getDeclaredNonStaticMembers(KClassImpl.kt)
	at kotlin.reflect.jvm.internal.KClassImpl$Data$allNonStaticMembers$2.invoke(KClassImpl.kt:148)
	at kotlin.reflect.jvm.internal.KClassImpl$Data$allNonStaticMembers$2.invoke(KClassImpl.kt:39)
	at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:93)
	at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:32)
	at kotlin.reflect.jvm.internal.KClassImpl$Data.getAllNonStaticMembers(KClassImpl.kt)
	at kotlin.reflect.jvm.internal.KClassImpl$Data$allMembers$2.invoke(KClassImpl.kt:154)
	at kotlin.reflect.jvm.internal.KClassImpl$Data$allMembers$2.invoke(KClassImpl.kt:39)
	at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:93)
	at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:32)
	at kotlin.reflect.jvm.internal.KClassImpl$Data.getAllMembers(KClassImpl.kt)
	at kotlin.reflect.jvm.internal.KClassImpl.getMembers(KClassImpl.kt:169)
	at kotlin.reflect.full.KClasses.getFunctions(KClasses.kt:90)
	at kotlin.reflect.jvm.ReflectJvmMapping.getKotlinFunction(ReflectJvmMapping.kt:137)
	at io.mockk.impl.instantiation.JvmMockFactoryHelper.varArgPosition(JvmMockFactoryHelper.kt:53)
	at io.mockk.impl.instantiation.JvmMockFactoryHelper.toDescription(JvmMockFactoryHelper.kt:69)
	at io.mockk.impl.instantiation.JvmMockFactoryHelper$mockHandler$1.invoke(JvmMockFactoryHelper.kt:16)
	at io.mockk.impl.instantiation.JvmMockFactoryHelper$mockHandler$1.invoke(JvmMockFactoryHelper.kt:12)
	at io.mockk.impl.instantiation.JvmMockFactoryKt$sam$MockKInvocationHandler$4dff1f07.invocation(JvmMockFactory.kt)
	at io.mockk.proxy.MockKProxyInterceptor.intercept(MockKProxyInterceptor.java:20)
	at android.database.Cursor$ByteBuddy$p9JdW6Uq$ByteBuddy$kCWr7SV9.getColumnIndex(Unknown Source)
	at com.showmax.lib.download.downloader.SomeTesrt$name$1.invoke(SomeTesrt.kt:22)
	at com.showmax.lib.download.downloader.SomeTesrt$name$1.invoke(SomeTesrt.kt:17)
	at io.mockk.impl.eval.RecordedBlockEvaluator$record$block$1.invoke(RecordedBlockEvaluator.kt:22)
	at io.mockk.impl.recording.JvmAutoHinter.autoHint(JvmAutoHinter.kt:23)
	at io.mockk.impl.eval.RecordedBlockEvaluator.record(RecordedBlockEvaluator.kt:31)
	at io.mockk.impl.eval.EveryBlockEvaluator.every(EveryBlockEvaluator.kt:25)
	at com.showmax.lib.download.downloader.SomeTesrt.name(SomeTesrt.kt:29)
	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.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:488)
	at org.robolectric.internal.SandboxTestRunner$2.evaluate(SandboxTestRunner.java:209)
	at org.robolectric.internal.SandboxTestRunner.runChild(SandboxTestRunner.java:109)
	at org.robolectric.internal.SandboxTestRunner.runChild(SandboxTestRunner.java:36)
	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.robolectric.internal.SandboxTestRunner$1.evaluate(SandboxTestRunner.java:63)
	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:51)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
	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.AppMainV2.main(AppMainV2.java:131)
Caused by: java.lang.InstantiationException: kotlin.reflect.jvm.internal.impl.load.java.JavaIncompatibilityRulesOverridabilityCondition
	at java.lang.Class.newInstance(Class.java:427)
	at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:380)
	... 93 more
Caused by: java.lang.NoSuchMethodException: kotlin.reflect.jvm.internal.impl.load.java.JavaIncompatibilityRulesOverridabilityCondition.<init>()
	at java.lang.Class.getConstructor0(Class.java:3082)
	at java.lang.Class.newInstance(Class.java:412)
	... 94 more


Process finished with exit code 255

Capturing in private suspend functions does not work

For example given the following class:

class MyClass {

  private suspend myPrivateCall(arg1) {
  
   }

}

And then in the test:

val myClassSpy = spyk(MyClass())

every { myClassSpy["myPrivateCall"](arg1) } returns "something"

Throws: java.lang.IllegalArgumentException: Callable expects X arguments, but Y were provided.

This only happens if the function is suspend private function.

NoClassDefFoundError: KClasses

When running my tests with version 1.4, I get the following error on all my tests:

java.lang.NoClassDefFoundError: kotlin/reflect/full/KClasses
	at io.mockk.impl.MockFactoryImpl.mockk(Factory.kt:27)

Exactly the same tests with version 1.3 works fine.

lateinit property has not been initialized

I have this code:

interface IFoo

class Foo:IFoo {
	fun method(){
		// ...
	}
}

abstract class AbstractBar<T:IFoo>{
    @Inject
    lateinit var foo: T
}



class Bar: AbstractBar<Foo>() {
    fun call(){
        foo.method()
    }
}

class Test {
    @MockK
    lateinit var foo: Foo

    @InjectMockKs lateinit var bar: Bar

    @Before
    fun setUp() = MockKAnnotations.init(this)


    @Test
    fun test() {
        every { foo.method() } answers { nothing }
        bar.call()
        verify { foo.method() }
    }
}

and it produces an error:
kotlin.UninitializedPropertyAccessException: lateinit property foo has not been initialized

mockk version: 1.7.12

What do I need to do to get it right? or is it a bug?

Missing equivalent for Mockito annotation @InjectMocks

Please add equivalent for annotation Mockito @JnjectMocks
Or is there any other way to automatically inject to @Inject annotated field

class UseCase {
  @Inject
  lateinit var service: Service
}

Currently I have to manually set it up

 private lateinit var useCase: UseCase

  @Before
  fun setUp() {
    MockKAnnotations.init(this)

    useCase = UseCase()
    useCase.service = service
  }

Verify with any ignores exactly

Specifying exactly=0 on a verify where an any() matcher is used results in a verification failure when a different call does happen on the mock . This should not be an error as the call did specified did not happen

Example from your io.mockk.it.VerifyAtLeastAtMostExactlyTest class.

class MockCls {
        fun op(a: Int) = a + 1
        fun op2(a: Int, b: Int) = a + b
    }

val mock = mockk<MockCls>()

@Test
    fun exactlyZeroWithAny() {
        doCalls()

        verify(exactly = 0) {
            mock.op2(3, any())
        }
    }

fun doCalls() {
        every { mock.op(0) } throws RuntimeException("test")
        every { mock.op(1) } returnsMany listOf(1, 2, 3)
        every { mock.op2(2, 1) } returns 3

        assertFailsWith(RuntimeException::class) {
            mock.op(0)
        }

        assertEquals(1, mock.op(1))
        assertEquals(2, mock.op(1))
        assertEquals(3, mock.op(1))
        assertEquals(3, mock.op(1))
        assertEquals(3, mock.op2(2, 1))
    }

Error:

java.lang.AssertionError: Verification failed: call 1 of 1: MockCls(#387).op2(eq(3), any())). Only one matching call to MockCls(#387)/op2(Int, Int) happened, but arguments are not matching:
[0]: argument: 2, matcher: eq(3), result: -
[1]: argument: 1, matcher: any(), result: +

Missing Feature? Mocking dynamic type

Use Case: In mockito I was doing this:

private void assertRequestClassWasUsed(final Class<? extends AbstractRequest> requestKlass, Runnable doIt, Consumer<QueueWriter> verification) {
        final QueueWriter queueWriter = expectedQueueWriter.get(requestKlass);
        assertThat(queueWriter).as("Could not find queuewriter for payload %s", requestKlass.getCanonicalName()).isNotNull();
        final AbstractRequest request = (AbstractRequest)mock(requestKlass);  //<-- This
        when(queueWriter.getName()).thenReturn(QUEUE_NAME);
        when(message.getPayload()).thenReturn(request);
        when(receivedMessage.getPayload()).thenReturn(request);
        doIt.run();
        verification.accept(queueWriter);
        Mockito.reset(primaryQueueWriter, refreshQueueWriter, harvestQueueWriter, createQueueWriter);

I cannot figure out a way in mockk to do the equivalent of mock(requestClass) where the class is not known at compile time. I fully admit that I am missing something here.

How to run it with Android Instrumentation Tests

I've been trying to run mockk with androi instrumentation test but no success.
I've added testCompile "io.mockk:mockk:1.7.10"
To my build.gradle
And I was able to run it perfectly as a unit test.
But if I try to run as an Instrumentation Test, I get a unresolved reference in io.mockk.*

If I add :
androidTestCompile "io.mockk:mockk:1.7.10"

I was able to build it, doesnt get the unresolved reference anymore, but when I run the test I got:
java.lang.NoClassDefFoundError: Failed resolution of: Ljava/lang/instrument/ClassFileTransformer;

Is there something I'm doing wrong, I really wish to use mockk it with android instrumentation tests.

Here is my Test section in my build.gradle

`

testCompile 'org.mockito:mockito-core:2.7.22'

androidTestCompile 'org.mockito:mockito-android:2.7.22'

androidTestCompile 'io.mockk:mockk:1.7.10'

testCompile 'com.nhaarman:mockito-kotlin-kt1.1:1.5.0'

testImplementation 'org.hamcrest:hamcrest-library:1.3'

testImplementation "com.squareup.retrofit2:retrofit-mock:${retrofitLibVersion}"

testImplementation 'org.mockito:mockito-inline:2.13.0'

testCompile ('org.threeten:threetenbp:1.3.2'){
    exclude group:'com.jakewharton.threetenabp', module:'threetenabp'
}
testCompile 'junit:junit:4.12'
testCompile "io.mockk:mockk:1.7.10"

`

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.