1、mock使用流程
-
0、初始化:必须使用@RunWith(MockitoJUnitRunner.class)或Mockito.initMocks(this)初始化这些模拟并注入它们。
-
1、创建mock对象:对于不容易构造的类, 使用注解@Mock构建虚拟对象
-
2、测试方法实现
-
构造参数
-
打桩:当执行该类中的某些方法时 指定输入输出
-
调用需要测试的方法
-
验证结果
-
参考:https://blog.csdn.net/moshowgame/article/details/100983711
2、@Mock、@Spy和@InjectMock的区别
-
Mock:创建一个虚拟对象。可以用来模拟方法的返回值,以便在测试中对其进行测试。
-
InjectMock:执行真实的方法,可以注入mock对象。(打桩推荐when……then)
-
spy:灵活控制真实执行/跳过方法。spy 对象是真实对象的代理,当你不对它进行设置的时候,所有的调用都会转发给真实的对象。如果你对 spy 对象进行了设置,那么这个设置将会覆盖真实对象的行为。
-
使用Spy包装真实对象时使用when(….).thenReturn(….)将无效,必须使用 doReturn(…).when(…)来进行插桩;
-
-
两种打桩区别:
-
when(...) thenReturn(...)会调用真实的方法,并返回指定结果。如果你不想调用真实的方法而是想要mock的话,就不要使用这个方法。
-
doReturn(...) when(...) 不会调用真实方法。
-
总的来说,`mock`用于创建本地伪造对象的对象, 而`injectmock`用于将伪造或模拟的对象添加到你的代码中。当我们在写单元测试时,我们可以使用Mock来代替需要复杂的对象或服务,以便我们可以集中精力测试特定的代码片段。而使用InjectMocks时, 开发人员可以将Mock对象注入到需要被测试的类中,并且可以测试类和Mock之间的交互和协作。
3、使用示例
-
Spy + Mock + InjectMock :执行真实的方法,同时又需要打桩,需要注入mock对象。
@RunWith(MockitoJUnitRunner.class) public class ParamPaddingComponentTest { //spy注解: 该实例执行真实的方法,且可以打桩 //InjectMocks注解: 可以将其他mock对象注入到ParamPaddingComponent @Spy @InjectMocks private ParamPaddingComponent paramPaddingComponent; //将依赖mock为虚拟对象 @Mock private MetaInfoHolder metaInfoHolder; @Before public void init() { } @Test public void testProcessNoParams() throws Exception { // 构造参数 ExecutionContext executionContext = new ExecutionContext(); executionContext.setApiUri("v1/test"); executionContext.setAppId("123456789"); Optional<Map> defaultValuesCfg = Optional.of(JsonUtils.fromJson("{\"audioFormat\":\"pcm\", \"sampleRate\":16000}", Map.class)); // 打桩 Mockito.doReturn(executionContext).when(paramPaddingComponent).getContextBean(Mockito.any()); Mockito.doReturn(defaultValuesCfg).when(metaInfoHolder).getFixedConfg(LionGroupEnum.API_DEFAULTVALUES_CFG.getGroupName(), "v1/test-123456789"); //调用方法 paramPaddingComponent.process(); //验证结果 Map<String, Object> expectResult = new ConcurrentHashMap<>(); expectResult.put("sampleRate", 16000); expectResult.put("audioFormat", "pcm"); Assert.assertEquals(expectResult, executionContext.getRequestParams()); } }
4、使用限制
-
不能 mock 静态方法
-
不能 mock private 方法
-
不能 mock final class