15

Mockito does not initialize a mock run with the JUnit 5 in a @BeforeAll annotated method. It works if I change the init's method annotation to @BeforeEach. Tests are run within IntelliJ IDEA.

My test class :

@ExtendWith(MockitoExtension.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class MyTest {
    
    private MyMockedClass myMockedClass;

    @BeforeAll
    public void init() {
        when(myMockedClass.getSomething()).thenReturn(something); // Mock is not initialized, getting NPE on test

Dependencies (only related ones are shown, others omitted for brevity):

[INFO] --- maven-dependency-plugin:2.10:tree (default-cli) @ XXX ---
[INFO] +- org.mockito:mockito-core:jar:3.6.28:test
[INFO] |  +- net.bytebuddy:byte-buddy:jar:1.10.18:compile
[INFO] |  +- net.bytebuddy:byte-buddy-agent:jar:1.10.18:test
[INFO] |  \- org.objenesis:objenesis:jar:3.1:test
[INFO] +- org.mockito:mockito-junit-jupiter:jar:3.6.28:test
[INFO] |  \- org.junit.jupiter:junit-jupiter-api:jar:5.7.0:test
[INFO] |     +- org.apiguardian:apiguardian-api:jar:1.1.0:test
[INFO] |     +- org.opentest4j:opentest4j:jar:1.2.0:test
[INFO] |     \- org.junit.platform:junit-platform-commons:jar:1.7.0:test
[INFO] +- org.springframework.boot:spring-boot-starter-test:jar:2.4.1:test
[INFO] |  +- org.junit.jupiter:junit-jupiter:jar:5.7.0:test
[INFO] |  |  +- org.junit.jupiter:junit-jupiter-params:jar:5.7.0:test
[INFO] |  |  \- org.junit.jupiter:junit-jupiter-engine:jar:5.7.0:test
[INFO] |  |     \- org.junit.platform:junit-platform-engine:jar:1.7.0:test
Mureinik
  • 297,002
  • 52
  • 306
  • 350
fg78nc
  • 4,774
  • 3
  • 19
  • 32
  • 2
    Have you annotated the `private MyMockedClass myMockedClass;` field with the `@Mock` annotation? As far as I remember the `@Mock` annotation is still required for Mockito to initialize mocks. – Thomas Kläger Jan 02 '21 at 20:22
  • Just out of curiosity: why do you need mocks in the `@BeforeAll` method? Why are mocks in the `@BeforeEach` method not sufficient? – Thomas Kläger Jan 03 '21 at 09:45
  • @ThomasKläger I am providing mock behavior (answer) in `@BeforeAll`. I do not want to re-run init method for each unit test. – fg78nc Jan 03 '21 at 18:41

3 Answers3

14

The MockitoExtension class implements the BeforeEachCallback but not the BeforeAllCallback from JUnit-Jupiter-API. It does therefore not provide any additional behaviour for @BeforeAll annotated methods.

Source extract of MockitoExtension

public class MockitoExtension implements BeforeEachCallback, AfterEachCallback, ParameterResolver {
Thomas Kläger
  • 17,754
  • 3
  • 23
  • 34
7

You're missing the initialization of the myMockedClass. Note that you can't use a @Mock annotation for it, because the @BeforeAll method would be run before that annotation is used to initialize the mocked object, and you'd have to resort to explicitly calling Mockito.mock:

@BeforeAll
public void init() {
    myMockedClass = mock(MyMockedClass.class); // Here
    when(myMockedClass.getSomething()).thenReturn(something);
}
GalAbra
  • 5,048
  • 4
  • 23
  • 42
Mureinik
  • 297,002
  • 52
  • 306
  • 350
  • 3
    `@BeforeAll` can be non-static (and I need it to be non-static in my case) if class is annotated with `@TestInstance(TestInstance.Lifecycle.PER_CLASS)` – fg78nc Jan 02 '21 at 20:06
  • @fg78nc arg, that was dumb of me, sorry about that. The problem is probably simpler - you didn't initialize the mock object. See my edited answer. – Mureinik Jan 02 '21 at 20:22
  • 5
    That's the essence of the question : Mockito should initialize mocks automatically by the virtue of presence of `@ExtendWith(MockitoExtension.class)` annotation. I do not want to initialize mock explicitly. As mentioned it works for with `@BeforeEach`. – fg78nc Jan 02 '21 at 20:26
  • @fg78nc The same snippet fails with the same `NullPointerException` even if you change it to a `BeforeEach` method. `MockitoExtension` won't mock test members that aren't annotated with `@Mock` (or something similar). – Mureinik Jan 02 '21 at 20:29
-1

it's a bit old but I found a solution that works for me :

public class MockitoExtensionBeforeAll extends MockitoExtension implements BeforeAllCallback, AfterAllCallback {

@Override
public void beforeAll(ExtensionContext context) {
    super.beforeEach(context);
}

@Override
public void afterAll(ExtensionContext context) {
    super.afterEach(context);
}

@Override
public void beforeEach(ExtensionContext context) {

}

@Override
public void afterEach(ExtensionContext context) {

}

}

Builder Bob
  • 151
  • 1
  • 10