
@Mock 是 Mockito 提供的便捷注解,用于自动创建模拟对象,但其初始化时机晚于 @BeforeClass,因此不能在静态预设方法中使用;若需在类级别初始化阶段创建 Mock,应改用 Mockito.mock() 手动实例化。
mockito 中 `@mock` 是 mockito 提供的便捷注解,用于自动创建模拟对象,但其初始化时机晚于 `@beforeclass`,因此不能在静态预设方法中使用;若需在类级别初始化阶段创建 mock,应改用 `mockito.mock()` 手动实例化。
在使用 Mockito 进行单元测试时,@Mock 注解常被误认为是 Mockito.mock(Class) 的简单语法糖——它确实能减少样板代码,但背后有严格的生命周期约束,理解这一点对编写健壮的测试至关重要。
@Mock 的本质与初始化时机
@Mock 并非在类加载或静态初始化阶段生效,而是由 MockitoJUnitRunner(或 MockitoExtension 在 JUnit 5 中)在每个测试实例创建后、@BeforeEach 方法执行前才完成字段注入和 Mock 对象初始化。这意味着:
- @Mock 字段必须是非静态的(private Object o;),否则 Mockito 无法通过反射设置其值;
- 它无法在 @BeforeClass(JUnit 4)或 @BeforeAll(JUnit 5)中使用,因为这些静态方法执行时,Mock 对象尚未创建,访问字段将导致 NullPointerException。
如下代码会失败:
@RunWith(MockitoJUnitRunner.class)
public class FooTest {
@Mock
private static Object o; // ❌ 编译虽通过,但运行时 o 始终为 null
@BeforeClass
public static void beforeClass() {
when(o.toString()).thenReturn("foo"); // NPE:o 未被初始化
}
}
正确的替代方案
若需在类级初始化阶段配置共享 Mock(例如复用昂贵的模拟依赖),推荐以下两种方式:
✅ 方式一:手动调用 Mockito.mock()(推荐)
@RunWith(MockitoJUnitRunner.class)
public class FooTest {
private static Object o;
@BeforeClass
public static void beforeClass() {
o = Mockito.mock(Object.class); // ✅ 显式创建,时机可控
when(o.toString()).thenReturn("foo");
}
@Test
public void test() {
assertEquals("foo", o.toString());
}
}
✅ 方式二:使用 @Before(非静态)配合 @Mock
@RunWith(MockitoJUnitRunner.class)
public class FooTest {
@Mock
private Object o; // ✅ 非静态字段,可被正确注入
@Before
public void setUp() {
when(o.toString()).thenReturn("foo"); // ✅ 安全调用
}
@Test
public void test() {
assertEquals("foo", o.toString());
}
}
⚠️ 注意:@Mock 与 @RunWith(MockitoJUnitRunner.class) 是强绑定的。若切换为 MockitoExtension(JUnit 5),需使用 @ExtendWith(MockitoExtension.class),且 @Mock 字段仍不可为 static。
总结:何时用 @Mock?何时手动 mock()?
| 场景 | 推荐方式 | 原因 |
|---|---|---|
| 每个测试方法需要独立、隔离的 Mock 实例 | @Mock + @Before | 自动管理生命周期,避免状态污染 |
| 类级别共享 Mock(如全局 stub 行为)、或需在 @BeforeClass 中预设 | Mockito.mock() 手动创建 | 完全掌控初始化时机,绕过框架限制 |
| 追求代码简洁性 & 测试可读性(非静态场景) | @Mock | 减少模板代码,语义清晰 |
简言之:@Mock 不是“多余”,而是为实例级测试场景而生的设计;它的限制恰恰体现了 Mockito 对测试隔离性和可预测性的坚持。合理选择初始化方式,才能让 Mock 既强大又可靠。











