《Java单元测试实战》——编写技巧:Java单元测试技巧之JSON序列化(4) https://developer.aliyun.com/article/1232284?groupCode=java
四、 测试资源使用案例
在上一章中,讲了测试用例和资源的命名规则以及存放方式。但是,只是文字的描述,没有什么体感。所有,这一章将举例一个完整的案例来实际说明。
1. 被测案例代码
以UserService的createUser方法为例说明:
/** * 用户服务类 */ @Service public class UserService { /** 服务相关 */ /** 用户DAO */ @Autowired private UserDAO userDAO; /** 标识生成器 */ @Autowired private IdGenerator idGenerator; /** 参数相关 */ /** 可以修改 */ @Value("${userService.canModify}") private Boolean canModify; /** * 创建用户 * * @param userCreate 用户创建 * @return 用户标识 */ public Long createUser(UserVO userCreate) { // 获取用户标识 Long userId = userDAO.getIdByName(userCreate.getName()); // 根据存在处理 // 根据存在处理: 不存在则创建 if (Objects.isNull(userId)) { userId = idGenerator.next(); UserDO userCreateDO = new UserDO(); userCreateDO.setId(userId); userCreateDO.setName(userCreate.getName()); userDAO.create(userCreateDO); } // 根据存在处理: 已存在可修改 else if (Boolean.TRUE.equals(canModify)) { UserDO userModifyDO = new UserDO(); userModifyDO.setId(userId); userModifyDO.setName(userCreate.getName()); userDAO.modify(userModifyDO); } // 根据存在处理: 已存在禁修改 else { throw new UnsupportedOperationException("不支持修改"); } // 返回用户标识 return userId; } }
2. 测试用例代码
编写完整的测试用例如下:
/** * 用户服务测试类 */ @RunWith(PowerMockRunner.class) public class UserServiceTest { /** 模拟依赖对象 */ /** 用户DAO */ @Mock private UserDAO userDAO; /** 标识生成器 */ @Mock private IdGenerator idGenerator; /** 定义测试对象 */ /** 用户服务 */ @InjectMocks private UserService userService; /** 定义静态常量 */ /** 资源路径 */ private static final String RESOURCE_PATH = "testUserService/"; /** * 在测试之前 */ @Before public void beforeTest() { // 注入依赖对象 Whitebox.setInternalState(userService, "canModify", Boolean.TRUE); } /** * 测试: 创建用户-创建 */ @Test public void testCreateUserWithCreate() { // 模拟依赖方法 // 模拟依赖方法: userDAO.getByName Mockito.doReturn(null).when(userDAO).getIdByName(Mockito.anyString()); // 模拟依赖方法: idGenerator.next Long userId = 1L; Mockito.doReturn(userId).when(idGenerator).next(); // 调用测试方法 String path = RESOURCE_PATH + "testCreateUserWithCreate/"; String text = ResourceHelper.getResourceAsString(getClass(), path + "userCreateVO.json"); UserVO userCreate = JSON.parseObject(text, UserVO.class); Assert.assertEquals("用户标识不一致", userId, userService.createUser(userCreate)); // 验证依赖方法 // 验证依赖方法: userDAO.getByName Mockito.verify(userDAO).getIdByName(userCreate.getName()); // 验证依赖方法: idGenerator.next Mockito.verify(idGenerator).next(); // 验证依赖方法: userDAO.create ArgumentCaptor<UserDO> userCreateCaptor = ArgumentCaptor.forClass(UserDO.class); Mockito.verify(userDAO).create(userCreateCaptor.capture()); text = ResourceHelper.getResourceAsString(getClass(), path + "userCreateDO.json"); Assert.assertEquals("用户创建不一致", text, JSON.toJSONString(userCreateCaptor.getValue())); // 验证依赖对象 // 验证依赖对象: idGenerator, userDAO Mockito.verifyNoMoreInteractions(idGenerator, userDAO); } /** * 测试: 创建用户-修改 */ @Test public void testCreateUserWithModify() { // 模拟依赖方法 // 模拟依赖方法: userDAO.getByName Long userId = 1L; Mockito.doReturn(userId).when(userDAO).getIdByName(Mockito.anyString()); // 调用测试方法 String path = RESOURCE_PATH + "testCreateUserWithModify/"; String text = ResourceHelper.getResourceAsString(getClass(), path + "userCreateVO.json"); UserVO userCreate = JSON.parseObject(text, UserVO.class); Assert.assertEquals("用户标识不一致", userId, userService.createUser(userCreate)); // 验证依赖方法 // 验证依赖方法: userDAO.getByName Mockito.verify(userDAO).getIdByName(userCreate.getName()); // 验证依赖方法: userDAO.modify ArgumentCaptor<UserDO> userModifyCaptor = ArgumentCaptor.forClass(UserDO.class); Mockito.verify(userDAO).modify(userModifyCaptor.capture()); text = ResourceHelper.getResourceAsString(getClass(), path + "userModifyDO.json"); Assert.assertEquals("用户修改不一致", text, JSON.toJSONString(userModifyCaptor.getValue())); // 验证依赖对象 // 验证依赖对象: idGenerator Mockito.verifyZeroInteractions(idGenerator); // 验证依赖对象: userDAO Mockito.verifyNoMoreInteractions(userDAO); } /** * 测试: 创建用户-异常 */ @Test public void testCreateUserWithException() { // 注入依赖对象 Whitebox.setInternalState(userService, "canModify", Boolean.FALSE); // 模拟依赖方法 // 模拟依赖方法: userDAO.getByName Long userId = 1L; Mockito.doReturn(userId).when(userDAO).getIdByName(Mockito.anyString()); // 调用测试方法 String path = RESOURCE_PATH + "testCreateUserWithException/"; String text = ResourceHelper.getResourceAsString(getClass(), path + "userCreateVO.json"); UserVO userCreate = JSON.parseObject(text, UserVO.class); UnsupportedOperationException exception = Assert.assertThrows("返回异常不一致", UnsupportedOperationException.class, () -> userService.createUser(userCreate)); Assert.assertEquals("异常消息不一致", "不支持修改", exception.getMessage()); // 验证依赖方法 // 验证依赖方法: userDAO.getByName Mockito.verify(userDAO).getIdByName(userCreate.getName()); // 验证依赖对象 // 验证依赖对象: idGenerator Mockito.verifyZeroInteractions(idGenerator); // 验证依赖对象: userDAO Mockito.verifyNoMoreInteractions(userDAO); } }
《Java单元测试实战》——编写技巧:Java单元测试技巧之JSON序列化(6) https://developer.aliyun.com/article/1232282?groupCode=java