0


用powermock编写单元测试

1、pom文件引入jar包

  1. <!-- 单元测试 start -->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-test</artifactId>
  5. <scope>test</scope>
  6. </dependency>
  7. <dependency>
  8. <groupId>junit</groupId>
  9. <artifactId>junit</artifactId>
  10. <scope>test</scope>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.powermock</groupId>
  14. <artifactId>powermock-module-junit4</artifactId>
  15. <version>2.0.2</version>
  16. <scope>test</scope>
  17. </dependency>
  18. <dependency>
  19. <groupId>org.powermock</groupId>
  20. <artifactId>powermock-api-mockito2</artifactId>
  21. <version>2.0.2</version>
  22. <scope>test</scope>
  23. </dependency>
  24. <dependency>
  25. <groupId>com.github.jsonzou</groupId>
  26. <artifactId>jmockdata</artifactId>
  27. <version>4.1.2</version>
  28. <scope>test</scope>
  29. </dependency>
  30. <!-- 单元测试 end -->

2、创建单元测试用例目录

保持与main级别一致,并且具体的测试用例存放目录也跟源代码的目录级别保持一致

8ce897237f8f56381fc80ddc386bd90a.png

cc2dabe8b7d178d93d043f4bb3cda1c9.png

3、单元测试类的基本框架

  1. @RunWith(PowerMockRunner.class)
  2. @PrepareForTest({CommonUtils.class}) // 工具类
  3. public class OrderServiceTest {
  4. @InjectMocks
  5. private OrderService orderService;
  6. @Mock
  7. private OrderMapper orderMapper;
  8. @Mock
  9. private OrderHelper orderHelper;
  10. @Before
  11. public void setUp() throws Exception {
  12. PowerMockito.mockStatic(CommonUtils.class);
  13. }
  14. // 被测试的方法 orderService.pageOrderRecord有返回值
  15. @Test
  16. public void testPageOrderRecord() {
  17. // Gievn
  18. OrderRecordDTO orderRecordDTO = new OrderRecordDTO();
  19. orderRecordDTO.setId("111");
  20. orderRecordDTO.setPageIndex(1);
  21. orderRecordDTO.setPageSize(10);
  22. // When
  23. OrderRecordEntity orderRecord = JMockData.mock(OrderRecordEntity.class);
  24. List<OrderRecordEntity> mock = Lists.newArrayList();
  25. mock.add(orderRecord);
  26. PowerMockito.when(orderMapper.selectEntityListPage(any())).thenReturn(mock); // mock的方法有返回值
  27. PowerMockito.doNothing().when(orderHelper).fillData(any()); // mock的方法没有返回值
  28. PowerMockito.when(CommonUtils.doPageQuery(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(new PageRows<>()); // mock工具类方法
  29. // Run the test
  30. PageRows<OrderRecordDTO> rt = orderService.pageOrderRecord(OrderRecordDTO);
  31. // Verify the results
  32. Assert.assertNotNull(rt);
  33. }
  34. }

4、常见单元测试问题

4.1、静态方法如何mock

参见基本框架里的CommonUtils.doPageQuery()的mock。

如果被测试类的方法中调用到了静态方法CommonUtils.doPageQuery(),在写测试类的时候就需要主要注意:

@PrepareForTest({CommonUtils.class})、

PowerMockito.mockStatic(CommonUtils.class);

4.2、返回类型为void的方法如何mock

参见基本框架里的orderHelper.fillData()方法的mock。

4.3、被@Value注解的值如何mock

** ReflectionTestUtils.setField(对象,"成员变量","变量mock值");**

被测试类:

  1. @Component
  2. public class OrderExternalFacade {
  3. @Autowired
  4. private OrderAbility OrderAbility;
  5. @Autowired
  6. private OrderExternalConvertor OrderExternalConvertor;
  7. @Value("${switch.new.system:false}")
  8. protected boolean switchNewSystem;
  9. public PageRows<OrderVO> listOrder(OrderQueryVO OrderQueryVO) {
  10. if (switchNewSystem) {
  11. return OrderExternalConvertor.pageDto2PageVo(
  12. OrderAbility.listOrder(OrderExternalConvertor.queryVo2ModelQuery(OrderQueryVO)));
  13. }
  14. return OrderExternalConvertor.pageDto2PageVo(
  15. OrderAbility.listOrderFromEpm(OrderExternalConvertor.queryVo2QueryDto(OrderQueryVO)));
  16. }
  17. }

单元测试类:

  1. @RunWith(PowerMockRunner.class)
  2. public class OrderExternalFacadeTest {
  3. @InjectMocks
  4. private OrderExternalFacade OrderExternalFacade;
  5. @Mock
  6. private OrderAbility OrderAbility;
  7. @Mock
  8. private OrderExternalConvertor OrderExternalConvertor;
  9. @Test
  10. public void listOrder() {
  11. ReflectionTestUtils.setField(OrderExternalFacade, "switchNewSystem", true);
  12. when(OrderExternalConvertor.queryVo2ModelQuery(any())).thenReturn(new OrderModelQueryDTO());
  13. when(OrderAbility.listOrder(any())).thenReturn(new PageRows<>());
  14. when(OrderExternalConvertor.pageDto2PageVo(any())).thenReturn(new PageRows<>());
  15. PageRows<OrderVO> rt = OrderExternalFacade.listOrder(new OrderQueryVO());
  16. Assert.assertNotNull(rt);
  17. }
  18. }

4.4、返回类型为void的方法如何断言

验证调用次数:verify(OrderService, times(1)).insertOrder(orderBO);

被测试类:

  1. public class OrderService{
  2. @Autowired
  3. private OrderDao OrderDao;
  4. /**
  5. * 添加订单
  6. * @param OrderBO
  7. * @throws Exception
  8. */
  9. @Override
  10. public void insertOrder(OrderBO OrderBO) throws Exception{
  11. OrderDao.insertOrder(OrderBO);
  12. }
  13. }

单元测试类:

  1. @RunWith(PowerMockRunner.class)
  2. public class OrderServiceTest {
  3. @InjectMocks
  4. private OrderService OrderService;
  5. @Mock
  6. private OrderDao OrderDao;
  7. @Before
  8. public void setUp() throws Exception {}
  9. @Test
  10. public void testinsertOrder() throws Exception {
  11. OrderBO orderBO = new OrderBO();
  12. orderBO.setHandleType("order");
  13. orderBO.setBoId("1234568");
  14. orderBO.setHandeleSuggest("submit");
  15. // 如何mock 返回类型为void的方法
  16. PowerMockito.doNothing().when(OrderDao).insertOrder(any());
  17. //when
  18. OrderService.insertOrder(orderBO);
  19. verify(OrderService, times(1)).insertOrder(orderBO);
  20. }
  21. }

4.5、异常如何断言

被测试类:

  1. public void delete(List<String> ids, String requiredBillId) {
  2. RequiredBillEntity requiredBill = requiredBillMapper.selectEntity(requiredBillId);
  3. if (requiredBill == null){
  4. throw new BusinessException(RetCode.BUSINESSERROR_CODE, MessageConst.REQUIRED_BILL_NOT_FOUND);
  5. }
  6. if (!RequiredBillStatusEnum.DRAFT.getStatus().equals(requiredBill.getStatus())){
  7. throw new BusinessException(RetCode.BUSINESSERROR_CODE, MessageConst.REQUIRED_BILL_STATUS_NOT_DRAFT);
  8. }
  9. requiredBillDetailMapper.deleteEntities(new ParamsMap("id_IN", ids));
  10. }

测试类:

  1. @Test
  2. public void testDelete() {
  3. List<String> ids = Lists.newArrayList();
  4. ids.add("dddd");
  5. String requiredBillId = "ddd";
  6. when(requiredBillMapper.selectEntity(anyString())).thenReturn(null);
  7. // 断言业务异常
  8. try {
  9. requiredBillDetailService.delete(ids,requiredBillId);
  10. fail("Expected BusiException");
  11. } catch (BusiException e) {
  12. assertEquals(RetCode.BUSINESSERROR_CODE, e.getExCode());
  13. assertEquals(REQUIRED_BILL_NOT_FOUND, e.getMessage());
  14. }
  15. }

简洁的一点的话:

  1. @Test
  2. public void testDelete() {
  3. List<String> ids = Lists.newArrayList();
  4. ids.add("dddd");
  5. String requiredBillId = "ddd";
  6. when(requiredBillMapper.selectEntity(anyString())).thenReturn(null);
  7. // 断言业务异常
  8. Assert.assertThrows(BusinessException.class, () ->requiredBillDetailService.delete(requiredBillDetailDTO));
  9. }
标签: 单元测试

本文转载自: https://blog.csdn.net/u010670619/article/details/136292536
版权归原作者 左弦月 所有, 如有侵权,请联系我们删除。

“用powermock编写单元测试”的评论:

还没有评论