3

I'm new to JUnit5 and I noticed something weird happening.

Let's see it with an example,

I have a source class named A

class A {
    someDownStreamService service;
    void printer() {
        int getData = service.getIntegerData();
        print(getData);
    }
}

Now when I wrote test case,

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class JUnit5TestCaseForClassA {
    @Mock
    private someDownStreamService service;   

    @InjectMocks
    private A a;

    @BeforeEach
    setUp() {
         initMocks(this);    
         Mockito.when(service.getIntegerData()).thenReturn(25);
    }

    @Test
    void test1() {
        a.printer();
    }

    @Test
    void test2() {
        Mockito.when(service.getIntegerData()).thenReturn(19);
        a.printer();
    }

}

When I trigger test2() individually, the printer() function is printing 19 as I suppose Mockito.when() statement is overridden to return 19 in test2() function over what was registered in @BeforeEach to return 25.

And when I execute all the test classes under class 'JUnit5TestCaseForClassA', I see that printer() function is printing 25 for both these test function's. Is the overriding not happening? Or what is the issue?

Why is this discrepancy?????

I can see making @TestInstance(TestInstance.Lifecycle.METHOD), will resolve the issue, as each testcases are triggered with new test instance. But I want to test with Lifecycle.PER_CLASS.

jumb0jet
  • 863
  • 6
  • 21
  • I cannot reproduce the behavior you have described using Mockito 2.28.2. What version of Mockito are you using? – Sam Brannen Jun 05 '19 at 09:10
  • 1
    The behaviour is happening when you set @TestInstance(TestInstance.Lifecycle.PER_CLASS) and mockito version : 2.23.4 and Junit 5 version : 5.4.0 – Manikandan Kbk DIP Jun 05 '19 at 09:13
  • I also have the same issue with junit version 5.7.1 and mockito version 3.6.28; this seems to be a bug. – maxeh Sep 13 '21 at 15:06

1 Answers1

0

I have slightly modified your example to make it testable (with assertions) as follows.

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import org.mockito.InjectMocks;
import org.mockito.Mock;

@TestInstance(Lifecycle.PER_CLASS)
public class MockitoJUnitJupiterTestCase {

    @Mock
    MyService service;

    @InjectMocks
    A a;

    @BeforeEach
    void setUp() {
        initMocks(this);
        when(service.getData()).thenReturn(25);
    }

    @Test
    void test1() {
        assertEquals("data: 25", a.printer());
    }

    @Test
    void test2() {
        when(service.getData()).thenReturn(19);
        assertEquals("data: 19", a.printer());
    }
}

interface MyService {

    int getData();
}

class A {

    MyService service;

    String printer() {
        return "data: " + service.getData();
    }
}

When I execute that using Mockito 2.23.4 or 2.28.2 and JUnit Jupiter 5.5 snapshots, the tests pass.

Can you try out this variation of your tests and let us know if both tests pass when executing the entire test class?

Sam Brannen
  • 29,611
  • 5
  • 104
  • 136
  • It can be recreated if you make `MyService service` in class A `final` and add a constructor to class A where `service` is set. I created a bug issue here: https://github.com/junit-team/junit5/issues/2718 – maxeh Sep 13 '21 at 16:12