如何在JUnit5 PER_CLASS生命周期下使用Mockito @InjectMocks
解决JUnit5 PER_CLASS生命周期下Mockito @Mock与@InjectMocks的注入问题
当测试类使用@TestInstance(TestInstance.Lifecycle.PER_CLASS)时,JUnit5只会创建一个测试类实例,但MockitoExtension默认会在每个测试方法执行前重新初始化@Mock对象,却不会将新创建的Mock重新注入到已存在的@InjectMocks实例中,导致后续测试方法仍使用第一次注入的旧Mock,新Mock无法生效,且无明确错误提示。
以下是两种简洁解决方案:
方案一:手动初始化Mock与注入(单次创建)
放弃Mockito注解的自动初始化逻辑,改用@BeforeAll在测试类初始化阶段仅执行一次Mock创建和注入,确保整个测试周期内Mock与被测试实例一一对应:
@ExtendWith(MockitoExtension::class) @TestInstance(TestInstance.Lifecycle.PER_CLASS) class MyTest { private lateinit var inner: InnerClass private lateinit var outer: OuterClass @BeforeAll fun setup() { inner = mock(InnerClass::class.java) // 方式1:直接构造注入(推荐,逻辑更直观) outer = OuterClass(inner) // 方式2:若依赖关系复杂,仍可使用Mockito注入API // outer = OuterClass() // MockitoAnnotations.openMocks(this).close() } @Test fun test1() { /* ... */ } @Test fun test2() { /* ... */ } }
方案二:重置Mock状态而非重建实例
保留Mockito注解的自动注入能力,在每个测试方法执行前重置Mock的交互记录、存根状态,避免创建新Mock但不注入的问题:
@ExtendWith(MockitoExtension::class) @TestInstance(TestInstance.Lifecycle.PER_CLASS) class MyTest { @Mock private lateinit var inner: InnerClass @InjectMocks private lateinit var outer: OuterClass @BeforeEach fun resetMockState() { reset(inner) } @Test fun test1() { /* ... */ } @Test fun test2() { /* ... */ } }
方案选择建议:
- 若仅需保证每个测试的Mock状态干净,方案二更简洁,保留了Mockito注解的便利性;
- 若必须在每个测试中使用全新Mock实例,方案一的手动构造注入逻辑更可靠。
内容的提问来源于stack exchange,提问作者tkruse
相关产品推荐
相关产品推荐

