如何正确Mock someService.method1().method2()的链式调用?
解决链式调用的Mock问题
要处理这种链式调用的Mock,核心是给链式调用里每一步返回的对象都做Mock,具体步骤如下:
假设someService.method1()返回的类型是SomeReturnType(请替换成你的代码里实际的返回类型),按下面的方式修改测试代码:
@AutoConfigureMockMvc class MyClassTest{ @MockBean SomeService someService; // 新增:Mock method1()返回的对象 @Mock SomeReturnType someReturnTypeMock; @Test void test1(){ // 第一步:指定调用someService.method1()时返回我们Mock的对象 when(someService.method1()).thenReturn(someReturnTypeMock); // 第二步:对链式调用的最后一步(void方法)设置doNothing doNothing().when(someReturnTypeMock).method2(); final MvcResult result = mockMvc.perform(get("/somepath")) .andExpect(status().isOk()) .andReturn(); } }
为什么原来的写法不行?
你之前直接写doNothing().when(someService.method1().method2()),此时someService.method1()还没被Mock,会返回null,调用null.method2()直接触发空指针异常。必须先让method1()返回一个Mock对象,再对这个对象的method2()做处理。
如果不想额外声明Mock对象,也可以用Mockito的RETURNS_DEEP_STUBS特性,不过这种方式可读性稍差,示例如下:
@AutoConfigureMockMvc class MyClassTest{ // 使用RETURNS_DEEP_STUBS创建支持深度Mock的实例 @MockBean(mockMode = MockBean.MockMode.MOCK, answer = Answers.RETURNS_DEEP_STUBS) SomeService someService; @Test void test1(){ doNothing().when(someService).method1().method2(); final MvcResult result = mockMvc.perform(get("/somepath")) .andExpect(status().isOk()) .andReturn(); } }
不过更推荐第一种方式,逻辑更清晰,也更容易维护。
内容的提问来源于stack exchange,提问作者zond
相关产品推荐
相关产品推荐

