Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: MockK is not runnable together with PowerMockito #79

Closed
3 tasks done
RafaRuiz opened this issue May 31, 2018 · 21 comments
Closed
3 tasks done

Bug: MockK is not runnable together with PowerMockito #79

RafaRuiz opened this issue May 31, 2018 · 21 comments

Comments

@RafaRuiz
Copy link

RafaRuiz commented May 31, 2018

Prerequisites

  • I am running the latest version
  • I checked the documentation and found no answer
  • I checked to make sure that this issue has not already been filed

Expected Behavior

Mocking a static method

Failure Information (for bugs)

java.lang.ExceptionInInitializerError
at my.package.ConfigUseCaseTests.getConfigs_fromJson(ConfigUseCaseTests.kt:33)
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)
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: io.mockk.MockKException: Failed to load plugin io.mockk.proxy.jvm.JvmMockKAgentFactory
at io.mockk.impl.JvmMockKGateway.(JvmMockKGateway.kt:152)
at io.mockk.impl.JvmMockKGateway.(JvmMockKGateway.kt:138)
... 29 more
Caused by: java.lang.IllegalStateException: Error during attachment using: net.bytebuddy.agent.ByteBuddyAgent$AttachmentProvider$Compound@1c72da34
at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:377)
at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:351)
at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:319)
at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:305)
at io.mockk.proxy.jvm.MockKInstrumentation.(MockKInstrumentation.java:57)
at io.mockk.proxy.jvm.JvmMockKAgentFactory.(JvmMockKAgentFactory.java:11)
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 java.lang.Class.newInstance(Class.java:442)
at io.mockk.impl.JvmMockKGateway.(JvmMockKGateway.kt:150)
... 30 more
Caused by: java.lang.reflect.InvocationTargetException
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 net.bytebuddy.agent.Attacher.install(Attacher.java:77)
at net.bytebuddy.agent.ByteBuddyAgent.install(ByteBuddyAgent.java:372)
... 41 more
Caused by: java.lang.NullPointerException
at com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:187)
... 47 more

Context

Please provide any relevant information about your setup. This is important in case the issue is not reproducible except for under certain conditions.

  • MockK version: 1.8.0
  • OS: Mac OS High Sierra
  • Kotlin version: 1.2.30
  • JDK version: 1.8.0_161
  • Type of test: unit test

Minimal reproducible code (the gist of this issue)

// These are some of the Gradle implementations.
    // Power Mockito
    testImplementation 'org.powermock:powermock-api-mockito:1.6.1'
    testImplementation 'org.powermock:powermock-module-junit4-rule-agent:1.6.1'
    testImplementation 'org.powermock:powermock-module-junit4-rule:1.6.1'
    testImplementation 'org.powermock:powermock-module-junit4:1.6.1'

    // Mockk
    testImplementation "io.mockk:mockk:1.8"

    // Mockito
    def mockitoVersion = "1.5.0"
    testImplementation "org.mockito:mockito-core:$mockitoVersion"
    testImplementation "com.nhaarman:mockito-kotlin-kt1.1:$mockitoVersion"
    androidTestImplementation("com.nhaarman:mockito-kotlin-kt1.1:$mockitoVersion", {
        exclude group: 'org.mockito', module: 'mockito-core'
    })
    androidTestImplementation 'org.mockito:mockito-android:2.11.0'

    class ConfigUseCaseTests : UnitTestsResource() {
    
        private lateinit var configUseCase: ConfigUseCase
    
        @Before
        override fun setUp() {
            super.setUp()
            configUseCase = ConfigUseCase()
        }
    
        @Test
        fun getConfigs_fromJson() {
            objectMockk(SharedPreferencesHelper).mock()
            every { SharedPreferencesHelper.loadString(isA(), isA(), isA(), isA()) } returns "wooo"
            System.out.println("String:${SharedPreferencesHelper.loadString(context, "", "", null)}")
        }
    }

I've also tested it with staticMockk or any other examples provided but I'm getting the same error.

@oleksiyp
Copy link
Collaborator

oleksiyp commented May 31, 2018

Looks like the agent is not attachable.

I know this is for windows, but try to put attach.so (I don't know how indeed it's called for macosx) in jdk/jre/lib to a PATH.

https://stackoverflow.com/questions/39420830/virtualmachine-attach-failing

(read show more comments)

@RafaRuiz
Copy link
Author

I've just realised that removing PowerMockito doesn't throw that.

@oleksiyp
Copy link
Collaborator

Oh, ok just was writting to try that.

@oleksiyp
Copy link
Collaborator

So it's powermock issue, because I was fixing integration with mockito already.

@RafaRuiz
Copy link
Author

Sorry to do another comment.
I'm using Mac OS not Windows in this case.

@oleksiyp
Copy link
Collaborator

Yeah I know, but attach.so should be in Linux and Mac OS X

@oleksiyp
Copy link
Collaborator

oleksiyp commented May 31, 2018

Anyway I'd like to reproduce and fix it if possible. Thanks for reporting

@RafaRuiz
Copy link
Author

Sure, what else would you need?

@oleksiyp
Copy link
Collaborator

I think I have enough information for now

@oleksiyp oleksiyp changed the title Can't integrate Mockk 1.7.0 Bug: MockK is not runnable together with PowerMockito May 31, 2018
@oleksiyp oleksiyp added the bug label May 31, 2018
@misrakli
Copy link

Hi,
thank You for the great work, we're using mockk successful in our projects.
But we faced the same problem with powermock. Any update for this issue in sight?

MockK : 1.8.3
PowerMock: 2.0.0-beta.5
Kotlin: 1.2.31

@oleksiyp
Copy link
Collaborator

Hi, no progress so far. If will have some spare time will check that

@karolzdebel
Copy link

We began integrating Mockk into our Android SDK over at Flybits however this issue is holding us back since many existing unit tests require PowerMock stubbing functionality.

@oleksiyp
Copy link
Collaborator

@karolzdebel
Can you provide build.gradle and minimal classes to reproduce it?
Because right now I am not able to reproduce it. Bumping at error although doing it from the documentation example:

org.mockito.exceptions.misusing.MissingMethodInvocationException: 
when() requires an argument which has to be 'a method call on a mock'.
For example:
    when(mock.getArticles()).thenReturn(articles);

Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
   Those methods *cannot* be stubbed/verified.
   Mocking methods declared on non-public parent classes is not supported.
2. inside when() you don't call method on mock but on some other object.

@karolzdebel
Copy link

karolzdebel commented Oct 25, 2018

@oleksiyp

Running the JavaClassTest below with the given gradle throws:

java.lang.NoClassDefFoundError: io/mockk/proxy/jvm/dispatcher/JvmMockKWeakMap

Gradle:

implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
testImplementation 'org.powermock:powermock-module-junit4:1.6.5'
testImplementation 'org.powermock:powermock-api-mockito:1.6.5'
testImplementation "io.mockk:mockk:1.8.9"
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'

Test class:

package com.example.karol.showcrashapp

import io.mockk.MockKAnnotations
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.powermock.modules.junit4.PowerMockRunner

@RunWith(PowerMockRunner::class)
class SomeJavaClassTest {

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

    }

    @Test
    fun someTest(){

    }
}

@oleksiyp
Copy link
Collaborator

oleksiyp commented Nov 11, 2018

At least I found some workaround. Provided example do not throw any exception. Do not know if it will work in general.

@RunWith(PowerMockRunner::class)
@PowerMockIgnore(
    "io.mockk.proxy.jvm.dispatcher.JvmMockKWeakMap",
    "io.mockk.proxy.jvm.dispatcher.JvmMockKDispatcher"
)
class SomeJavaClassTest {

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

    }

    @Test
    fun someTest(){

    }
}

@oleksiyp
Copy link
Collaborator

oleksiyp commented Nov 11, 2018

I played a bit more. Following code is printing for me null for some reason.

@RunWith(PowerMockRunner::class)
@PowerMockIgnore(
    "io.mockk.proxy.jvm.dispatcher.JvmMockKWeakMap",
    "io.mockk.proxy.jvm.dispatcher.JvmMockKDispatcher"
)
class SomeJavaClassTest {
    open class Tst(val x: Int = 5) {
        open fun tst() = "abc$x"
    }

    @Test
    fun testPowerMock(){
        val tst = Tst(6)
        PowerMockito.whenNew(Tst::class.java)
            .withAnyArguments()
            .thenReturn(tst)
        println(Tst())
    }
}

There is no MockK involved here at all and thus it should not load. Somebody should check if these workarounds are really working. If yes I can submit PR to PowerMock to include this as a permanent solution.

The general conclusion is that MockK lacks integration tests with other frameworks.

@pentiumao
Copy link

I played a bit more. Following code is printing for me null for some reason.

@RunWith(PowerMockRunner::class)
@PowerMockIgnore(
    "io.mockk.proxy.jvm.dispatcher.JvmMockKWeakMap",
    "io.mockk.proxy.jvm.dispatcher.JvmMockKDispatcher"
)
class SomeJavaClassTest {
    open class Tst(val x: Int = 5) {
        open fun tst() = "abc$x"
    }

    @Test
    fun testPowerMock(){
        val tst = Tst(6)
        PowerMockito.whenNew(Tst::class.java)
            .withAnyArguments()
            .thenReturn(tst)
        println(Tst())
    }
}

There is no MockK involved here at all and thus it should not load. Somebody should check if these workarounds are really working. If yes I can submit PR to PowerMock to include this as a permanent solution.

The general conclusion is that MockK lacks integration tests with other frameworks.

@oleksiyp Not worked for my project until I changed the code as below :

@PowerMockIgnore(
    "io.mockk.proxy.*"
)

This is like the case that Robolectric will encounter also.
Robolectric : Using-PowerMock

@zsoltvilagos
Copy link

Hi @oleksiyp !
I see this issue is Closed, not 100% clear with what result, so let me ask:
We're using

  • Mockito 2.26.0
  • PowerMock 2.0.2
  • MockK 1.9.3 with such a test:
@RunWith(PowerMockRunner::class)
@PrepareForTest(value = [AndroidUtils::class, StringUtils::class])
class CalculateImplTest {

    @Test
    fun calculate() {
        // given
        mockCurrentDateTime(2019, Calendar.APRIL, 7, 8, 0, 0)
        // ...
    }

    private fun mockCurrentDateTime(year: Int, month: Int, date: Int, hourOfDay: Int, minute: Int, second: Int) {
        mockkObject(DateUtils)

        every { DateUtils.provideCalendar() } returns Calendar.getInstance().apply { set(year, month, date, hourOfDay, minute, second) }
    }
}

Without problem! Is this issue maybe gone?

@stale
Copy link

stale bot commented Sep 14, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. If you are sure that this issue is important and should not be marked as stale just ask to put an important label.

@stale stale bot added the stale label Sep 14, 2019
@stale stale bot closed this as completed Sep 21, 2019
@oleksiyp oleksiyp removed the stale label Nov 2, 2019
@oleksiyp oleksiyp reopened this Nov 2, 2019
@sabrinaj
Copy link

Hello,

In case it might help someone else, I had the same issue and it was caused by org.powermock:powermock-module-junit4-rule-agent. Error was gone once we removed this dependency.

With these versions:

jUnitVersion = '4.13'
powerMockVersion = '2.0.2'
mockitoVersion = '2.26.0'
mockKVersion = '1.9.3'

@Raibaz
Copy link
Collaborator

Raibaz commented Nov 21, 2020

Closing this as looks like there's not much to do about this specifically other than making sure Mockk plays well with other testing and mocking frameworks.

@Raibaz Raibaz closed this as completed Nov 21, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants