这里以DemoController为例,Controller中调用了DemoService,代码如下:
@RestController
@RequestMapping("demo")
@Slf4j
public class DemoController {
@Autowired
private DemoService demoService;
@GetMapping(value = "/service1")
public String service1(String param1, Integer param2) {
String result = demoService.service1(param1, param2);
return result;
}
@GetMapping(value = "/service2")
public Boolean service2(Long a, Long b) {
Boolean result = demoService.service2(a, b);
return result;
}
@GetMapping(value = "/service3")
public DemoBean service3(String id) {
DemoBean result = demoService.service3(id);
return result;
}
@GetMapping(value = "/service4")
public DemoBean service4(DemoBean demoBean) {
DemoBean result = demoService.service4(demoBean);
return result;
}
}
public interface DemoService {
String service1(String param1, Integer param2);
Boolean service2(Long a, Long b);
DemoBean service3(String id);
DemoBean service4(DemoBean demoBean);
}
DemoService的实现类都返回null,代表未开发状态。
下面我们来看看怎么写这个controller的单元测试。
首先使用@InjectMocks注解DemoController:
@InjectMocks
private DemoController demoControllerMock;
然后使用@Mock注解controller中调用的第三方类,这里就是指DemoService:
@Mock
private DemoService demoService;
最后就是对应方法的测试方法了:
@Test
public void test01_01_service1() {
//模拟动作
Mockito.doReturn("aaa").when(demoService).service1(Mockito.anyString(), Mockito.anyInt());
//调用接口
String result = demoControllerMock.service1("abc", 233);
log.info("service1 返回:" + result);
//验证返回值
Assert.assertEquals(result, "aaa");
}
模拟动作就是模拟controller中怎么调用service了,doReturn就是你想让service方法返回的值,when就是指模拟哪个service,service1就是实际调用的方法名了,参数Mockito.anyXxx()就是根据service方法的形参来的,这里代表任意符合参数类型的内容。
模拟动作配置好后,再调用接口,返回值就是模拟动作中doReturn中设置的内容了。
如果对应方法返回值是实体类或集合类型,就需要首先将数据组织起来:
@Test
public void test03_01_service3() {
//组织数据
DemoBean demoBean = new DemoBean();
demoBean.setName("wang");
demoBean.setNumber(200);
List<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
demoBean.setList(list);
//模拟动作
Mockito.doReturn(demoBean).when(demoService).service3(Mockito.anyString());
//调用接口
DemoBean result = demoControllerMock.service3("abc");
log.info("service3 返回:" + JSON.toJSONString(result));
//验证返回值
Assert.assertNotNull(result);
}
如果第三方类不是service,而是远程调用接口的话,需要先获取远程调用接口的返回json串:
//组织数据
String returnStr = "{\"timeStamp\": \"1560131834846\", \"returnCode\": \"0000\", \"beans\": [], \"returnMessage\": \"sucess\",\"bean\": {} }";
然后封装成远程调用的response
//模拟动作
Mockito.doReturn(response).when(iXxxSV).service(Mockito.any());
这样,当代码运行到远程调用接口时,就不会去请求远程接口,而是直接返回response的内容了。
增加对异常分支的支持:
Controller:
@GetMapping(value = "/service5")
public DemoBean service5(String id) {
DemoBean result = null;
try {
result = demoService.service5(id);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
Service:
DemoBean service5(String id) throws Exception;
Test:
@Test
public void service5() throws Exception {
//模拟动作
Mockito.doThrow(new Exception("模拟覆盖异常分支")).when(demoService).service5(Mockito.any());
//如果第三方接口没有throw异常,上面这句会报错,需要如下写法
Mockito.doThrow(Exception.class).when(demoService).service5(Mockito.any());
DemoBean result = demoControllerMock.service5("abc");
log.info("service5 返回:" + JSON.toJSONString(result));
Assert.assertNull(result);
}
最后修改于 2019-07-19 14:35:42
如果觉得我的文章对你有用,请随意赞赏
扫一扫支付

