在@BeforeAll 注释方法中使用 JUnit 5 运行的测试中,Mockito 不会初始化模拟

fg7*_*8nc 2 java mockito junit5 junit5-extension-model

Mockito 不会在 @BeforeAll 注释方法中使用 JUnit 5 初始化模拟运行。如果我将 init 方法注释更改为 @BeforeEach,它会起作用。测试在 IntelliJ IDEA 中运行。

我的测试课:

@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
Run Code Online (Sandbox Code Playgroud)

依赖关系(仅显示相关的,为简洁起见省略了其他的):

[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
Run Code Online (Sandbox Code Playgroud)

Mur*_*nik 7

您缺少myMockedClass. 请注意,您不能@Mock为其使用注释,因为该@BeforeAll方法将在使用该注释初始化模拟对象之前运行,并且您必须显式调用Mockito.mock

@BeforeAll
public void init() {
    myMockedClass = mock(MyMockedClass.class); // Here
    when(myMockedClass.getSomething()).thenReturn(something);
}
Run Code Online (Sandbox Code Playgroud)

  • 这就是问题的本质:Mockito 应该通过 @ExtendWith(MockitoExtension.class) 注释的存在自动初始化模拟。我不想显式初始化模拟。如前所述,它适用于“@BeforeEach”。 (6认同)
  • 如果类用“@TestInstance(TestInstance.Lifecycle.PER_CLASS)”注释,“@BeforeAll”可以是非静态的(在我的情况下,我需要它是非静态的) (3认同)

Tho*_*ger 5

MockitoExtension类实现BeforeEachCallback,但不是BeforeAllCallback从JUnit的木星的API。因此,它不会为带@BeforeAll注释的方法提供任何额外的行为。

来源摘录 MockitoExtension

public class MockitoExtension implements BeforeEachCallback, AfterEachCallback, ParameterResolver {
Run Code Online (Sandbox Code Playgroud)