question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Different mocks are used for @Mock and @InjectMock when using @TestInstance(TestInstance.Lifecycle.PER_CLASS) of jUnit5

See original GitHub issue

Hi,

I have a problem which seems to be very similar to this one https://github.com/mockito/mockito/issues/1346 but it is happening when I run test with @TestInstance(TestInstance.Lifecycle.PER_CLASS) (which is a better thing to do in Kotlin).

For the following code, the first iteration is working and the following are not because the behavior of another mock is changed 😰(foo.bar isn’t the same as bar)

class Bar {
    fun call() = 42
}

class Foo(val bar: Bar) {
    fun call() = bar.call() + 23
}

@TestInstance(TestInstance.Lifecycle.PER_CLASS) // If this is remove, all is ok
@ExtendWith(MockitoExtension::class)
class HelloTest {

    @Mock lateinit var bar: Bar
    @InjectMocks lateinit var foo: Foo

    @RepeatedTest(4)
    fun `should return 24`() {
        /* Given */
        whenever(bar.call()).thenReturn(1)
        /* When */
        val r = foo.call()
        /* Then */
        assertThat(r).isEqualTo(24)
    }

    @RepeatedTest(4)
    fun `@InjectMocked foo should have same bar as bar`() {
        assertThat(foo.bar).isSameAs(bar)
    }
}

We can also see this in the IDE :

First time: image

Second time: image

Of course, if I remove the @TestInstance(TestInstance.Lifecycle.PER_CLASS), all is now OK.

I’m running on the last version 2.19.1 with jUnit 5.2.0. You can see the full example here :

https://github.com/davinkevin/issue-mockito-junit5-kotlin

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:5
  • Comments:21 (16 by maintainers)

github_iconTop GitHub Comments

2reactions
vgherocommented, Mar 4, 2022

Hey, today we also ran into this, being confused why it works for the test in isolation but not when running all test together. Then we saw that setting @TestInstance(TestInstance.Lifecycle.PER_METHOD) makes it work. Finally ending up here. Is there any progress on this? We also have just ctor injection and in there we set the value into a final field. So code-wise it’s a common case. Also if not fixable in the near future, should Mockito better fail on such situations (if detectable) or at least adding a hint to @InjectMocks javadoc could help?

2reactions
slawekjaranowskicommented, Dec 11, 2020

Last time I did some refresh and refactor in mockito-testng project.

Now mockito-testng simply call Mockito.mockitoSession()....startMocking();

There are no any manual management for mocks and other injections.

TestNG has by design one instance of test class.

In similar case @InjectMocks inject correct mock into annotated class.

One case where class with @InjectMocks has old value is when we have class with constructor and value is stored in final field.

final field are not refreshed before next test.

Another workaround can be set null to field which should have injected mock in some of after method, so class will be created with corrected injections.

Read more comments on GitHub >

github_iconTop Results From Across the Web

@TestInstance Annotation in JUnit 5 | Baeldung
In this tutorial, we are going to learn how JUnit 5 allows us to modify the lifecycle of the test class using the...
Read more >
Mockito does not initialize mock in test running with JUnit 5 in ...
Tests are run within IntelliJ IDEA. My test class : @ExtendWith(MockitoExtension.class) @TestInstance(TestInstance.Lifecycle.PER_CLASS) public ...
Read more >
Using Mockito With JUnit 5 | Code With Arho
In this article, we will learn how to use the Mockito mocking framework with JUnit 5. We will learn a test framework independent...
Read more >
Java Best Practices - Lombok, JUnit 5 and Mockito - Zhenye Na
How to properly use Lombok, Junit and Mockito in Java. ... in a @Nested test class unless the “per-class” test instance lifecycle is...
Read more >
A Comprehensive Guide On JUnit 5 Extensions - LambdaTest
JUnit 5 can only be used with Java versions greater than or equal to 8 ... In the primary test instance lifecycle, JUnit...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found