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

Mockk lost support for parallel test execution in version 1.13.7 #1133

Closed
3 tasks done
bay73 opened this issue Aug 16, 2023 · 10 comments · Fixed by #1238
Closed
3 tasks done

Mockk lost support for parallel test execution in version 1.13.7 #1133

bay73 opened this issue Aug 16, 2023 · 10 comments · Fixed by #1238

Comments

@bay73
Copy link

bay73 commented Aug 16, 2023

It seems the version 1.13.7 has lost support for parallel execution. I would blame this change: #1099.
clearAllMocks is known to not be thread safe and now it is called after each test. In previous version the issue with clearAllMocks could have been avoided by putting tests which use this function out of parallel execution scope. Now the issue affects all tests and parallel execution seems completely impossible.

  • 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

When using systemProperty("junit.jupiter.execution.parallel.enabled", "true") in gradle setting for test task I would expect test results to be the same as for disabled parallel execution.

Current Behavior

Many tests fail with
io.mockk.MockKException: no answer found for <some mock> among the configured answers

Steps to Reproduce

Put systemProperty("junit.jupiter.execution.parallel.enabled", "true") into your build.gradle.kts file

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.13.7
  • Kotlin version: 1.9.0
  • JUnit version: 5.6.2
  • Type of test: unit test
@Evenprime
Copy link
Contributor

Running into the same issue, when using the MockKExtension for unit-testing with latest mockK version, and the following settings enabled on a rather large project with over 1000 tests:

systemProperty("junit.jupiter.execution.parallel.enabled", "true")
systemProperty("junit.jupiter.execution.parallel.mode.classes.default", "concurrent")

So running classes in parallel, but tests within each class sequentially. In case it makes a difference for reproducing/tracking down the issue.

@Raibaz
Copy link
Collaborator

Raibaz commented Aug 28, 2023

Ah, you're right, calling clearAllMocks on every test run is definitely going to break parallel execution.

Sorry about this.

Would it be helpful if we called clearAllMocks on every test run by default but added a configuration flag to disable it, so that you can prevent it from being called when running tests in parallel?

@Evenprime
Copy link
Contributor

That would help me in my case already a lot.

@lifey
Copy link

lifey commented Jan 16, 2024

@Raibaz Hi is there a plan to make clearAllMocks configurable ? Can I help somehow ?
We cannot upgrade mockk as this break our parallelism

@Evenprime
Copy link
Contributor

We ended up writing a custom test extension class and using that instead of the official MockKExtension implementation:

import io.mockk.MockKAnnotations
import io.mockk.unmockkAll
import org.junit.jupiter.api.extension.AfterAllCallback
import org.junit.jupiter.api.extension.ExtensionContext
import org.junit.jupiter.api.extension.TestInstancePostProcessor

class CustomMockKExtension : TestInstancePostProcessor, AfterAllCallback {
    override fun postProcessTestInstance(
        testInstance: Any,
        context: ExtensionContext,
    ) {
        MockKAnnotations.init(testInstance)
    }

    override fun afterAll(context: ExtensionContext) {
        unmockkAll()
    }
}

// Used simply as:

@ExtendWith(CustomMockKExtension::class)
class MyTestClass {
   // test class using @MockK, @InjectMockKs etc. as usual
}

That works well for us, as we don't use MockKs advanced features like static mocks, which would anyway prevent parallel tests. Depending on your usecases, you may need more logic from the official MockKExtension class copied in your own custom implementation.

@huisam
Copy link

huisam commented Feb 13, 2024

Hello @Raibaz Does Mockk team has a plan to support a extension for parallel test? I cannot upgrade mockk version either as this issue

If not, I have to write the custom extension to maintain the parallel execution.

@Raibaz
Copy link
Collaborator

Raibaz commented Feb 16, 2024

I took a look at this and the fix was easier than I expected.

I'm going to add a requireParallelTesting configuration setting to disable calling clearAllMocks after each test execution.

@vilikin
Copy link

vilikin commented Mar 4, 2024

Hello @Raibaz,

Is there maybe a bug still in the code that you added to fix the issue? It looks to me like clearAllMocks is called only when parallel testing is required, even though it should be the opposite - right? Or have I misunderstood something badly?

Also, regardless of how requireParallelTests is configured, it does not currently matter as if keepMocks is set to false (like it is by default), then that already forces clearAllMocks to be called.

@Evenprime
Copy link
Contributor

vilikin is correct, the current implementation of that flag is broken and doesn't actually enable us to skip the call to clearAllMocks the way it was intended.

I attached a pull request with what I'd consider to be the proper logic for this flag.

@Raibaz
Copy link
Collaborator

Raibaz commented Apr 2, 2024

Ah, you're right, thanks for looking into this and sending #1238!

I'll merge it as soon as the builds pass

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants