如何通过全局配置或注解标记自定义类,禁止Mockito的MockedStatic静态模拟
全局禁止Mockito对特定类的静态/普通模拟
针对你的需求——让SpecialClass无法被Mockito的MockedStatic或普通mock方法模拟,就像java.lang.System那样——我们可以通过自定义Mockito的全局配置来实现,确保团队所有成员都无法误用。以下是适配Mockito 4.3.1版本的具体步骤:
1. 实现自定义的类型可模拟性检查类
我们需要创建一个类来拦截Mockito的可模拟性判断逻辑,添加对SpecialClass的限制:
import org.mockito.internal.creation.TypeMockability; import org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker; public class RestrictedTypeMockability implements TypeMockability { private final TypeMockability delegate; public RestrictedTypeMockability(TypeMockability delegate) { // 包装默认的可模拟性检查逻辑 this.delegate = delegate; } @Override public boolean isMockable(Class<?> type) { // 禁止SpecialClass及其子类被模拟 if (SpecialClass.class.isAssignableFrom(type)) { return false; } // 保留Mockito原有的检查规则(比如禁止模拟系统类) return delegate.isMockable(type); } @Override public String getNotMockableReason(Class<?> type) { if (SpecialClass.class.isAssignableFrom(type)) { return "It is not possible to mock " + type.getName() + " - this class is restricted from mocking to prevent misuse."; } return delegate.getNotMockableReason(type); } }
2. 配置Mockito全局加载自定义规则
创建一个MockitoConfiguration类并放在org.mockito.configuration包下(Mockito会自动扫描并使用这个包下的配置类),用来替换默认的可模拟性检查:
package org.mockito.configuration; import org.mockito.internal.creation.TypeMockability; import org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker; import com.yourcompany.yourpackage.RestrictedTypeMockability; // 替换为你的实际包路径 public class MockitoConfiguration extends DefaultMockitoConfiguration { @Override public TypeMockability getTypeMockability() { // 获取默认的inline mock maker的检查逻辑 TypeMockability defaultMockability = new InlineByteBuddyMockMaker().getTypeMockability(); // 用我们自定义的规则包装它 return new RestrictedTypeMockability(defaultMockability); } }
3. 验证效果
现在,当有人尝试运行你提供的测试代码,或者任何模拟SpecialClass的代码时,都会抛出如下异常:
org.mockito.exceptions.base.MockitoException: It is not possible to mock com.yourcompany.yourpackage.SpecialClass - this class is restricted from mocking to prevent misuse.
这个配置是全局生效的,不管是静态模拟(MockedStatic)还是普通对象模拟(mock(SpecialClass.class))都会被阻止,完全满足你的需求。
注意事项
- 该方案依赖Mockito的内部API,虽然在4.3.1版本中稳定,但如果后续升级Mockito大版本,可能需要根据内部API的变化调整实现。
- 如果你只需要禁止静态模拟而保留普通模拟,可以修改
RestrictedTypeMockability的判断逻辑,但从你的描述来看,完全禁止模拟更符合你的场景。
内容的提问来源于stack exchange,提问作者alea
相关产品推荐
相关产品推荐

