【问题标题】:Mockito does not initialize mock in test running with JUnit 5 in @BeforeAll annotated methodMockito 不会在 @BeforeAll 注释方法中使用 JUnit 5 运行测试中初始化模拟
【发布时间】:2021-04-09 02:35:43
【问题描述】:

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

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

[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

【问题讨论】:

  • 您是否使用@Mock 注释对private MyMockedClass myMockedClass; 字段进行了注释?据我记得 @Mock 注释仍然是 Mockito 初始化模拟所必需的。
  • 只是出于好奇:为什么在@BeforeAll 方法中需要模拟?为什么 @BeforeEach 方法中的 mock 不够?
  • @ThomasKläger 我在@BeforeAll 中提供模拟行为(答案)。我不想为每个单元测试重新运行 init 方法。

标签: java mockito junit5 junit5-extension-model


【解决方案1】:

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

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

【讨论】:

  • @BeforeAll 可以是非静态的(在我的情况下我需要它是非静态的),如果类用 @TestInstance(TestInstance.Lifecycle.PER_CLASS) 进行注释
  • @fg78nc arg,我太傻了,对此感到抱歉。问题可能更简单——您没有初始化模拟对象。请参阅我编辑的答案。
  • 这就是问题的本质:Mockito 应该通过 @ExtendWith(MockitoExtension.class) 注释的存在自动初始化模拟。我不想显式初始化模拟。如前所述,它适用于@BeforeEach
  • @fg78nc 即使您将其更改为 BeforeEach 方法,相同的 sn-p 也会以相同的 NullPointerException 失败。 MockitoExtension 不会模拟未使用 @Mock(或类似名称)注释的测试成员。
【解决方案2】:

MockitoExtension 类实现了 JUnit-Jupiter-API 中的 BeforeEachCallback,但没有实现 BeforeAllCallback。因此,它不为 @BeforeAll 带注释的方法提供任何其他行为。

MockitoExtension的源代码摘录

public class MockitoExtension implements BeforeEachCallback, AfterEachCallback, ParameterResolver {

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-06
    • 2011-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-15
    • 1970-01-01
    相关资源
    最近更新 更多