测试驱动开发(TDD)在微服务中的应用

绝地灬酷狼 2023-08-17 15:31 171阅读 0赞

在上一篇文章中用一个计算长方形面积的小例子介绍了如何使用TDD,感兴趣的小伙伴可以去阅读一下,今天主要介绍TDD是如何应用在微服务中的。我们还是先来回归一下TDD的三条实践准则。

TDD的三条准则
  • 除非为了使一个失败的单元测试通过,否则不允许编写任何业务代码。
  • 在一个单元测试中,只允许写一个刚好导致失败的内容。
  • 只允许编写刚好能够使一个失败的单元测试通过的业务代码。
开发环境
  • Java 8
  • Spring Boot 2.1.x
  • Spring Data JPA 2.0.9
  • TestNG 6.13
  • Mockito 1.10.19(创建虚拟对象,解耦依赖的类或者接口)
1.编写测试用例
  1. @InjectMocks
  2. SageTaxService sageTaxService = new SageTaxServiceImpl();
  3. @Mock
  4. SageTaxRepository sageTaxRepository;
  5. @Mock
  6. CommonService commonService;
  7. @Mock
  8. WebContext webContext;
  9. @Test
  10. public void test_add_sage_tax() {
  11. UserInfo userInfo = new UserInfo();
  12. userInfo.setUserId(999);
  13. Mockito.when(webContext.getUserInfo()).thenReturn(userInfo);
  14. SageTax sageTax = new SageTax();
  15. sageTax.setEntryId(webContext.getUserInfo().getGlobalUserId());
  16. sageTax.setEntryDatetime(commonService.getDbTimestamp());
  17. sageTax.setTaxRate(BigDecimal.valueOf(0.011));
  18. sageTax.setTaxIdCode("test");
  19. sageTax.setCountryCode("CA");
  20. sageTax.setTaxCode("qqq");
  21. Mockito.when(sageTaxRepository.save(sageTax)).thenReturn(sageTax);
  22. Assert.assertNotNull(sageTaxService.addSageTax(sageTax));
  23. }
2.运行测试用例

就会看到测试case运行失败了(因为你还没写功能代码)

3.编写业务代码
  1. @Override
  2. public Boolean addSageTax(SageTax sageTaxVO) {
  3. List<SageTax> sageTaxList = Lists.newArrayList();
  4. if (sageTaxVO.getCountryCode() != null && sageTaxVO.getTaxCode() != null) {
  5. // countryCode and taxCode is unique key
  6. sageTaxList = getSageTax(sageTaxVO.getCountryCode(), sageTaxVO.getTaxCode());
  7. }
  8. if (sageTaxList.size() > 0) {
  9. // if has data in DB, return false
  10. return false;
  11. }
  12. SageTax sageTax = new SageTax();
  13. sageTax.setEntryId(webContext.getUserInfo().getGlobalUserId());
  14. sageTax.setEntryDatetime(commonService.getDbTimestamp());
  15. sageTax.setTaxId(sageTaxVO.getTaxId());
  16. sageTax.setTaxIdCode(sageTaxVO.getTaxIdCode());
  17. sageTax.setCountryCode(sageTaxVO.getCountryCode());
  18. sageTax.setTaxCode(sageTaxVO.getTaxCode());
  19. sageTax.setTaxRate(sageTaxVO.getTaxRate());
  20. sageTaxRepository.save(sageTax);
  21. return true;
  22. }
4.运行测试用例,然后看到测试用例通过了
5.对代码查缺补漏,进行重构
  • 补充测试用例,因为可能在保存的时候会出错,所以新增一个case用来覆盖抛出exception的情况。

    @Test(expectedExceptions = Exception.class)

    1. public void test_add_sage_tax_with_exception() {
    2. UserInfo userInfo = new UserInfo();
    3. userInfo.setUserId(999);
    4. Mockito.when(webContext.getUserInfo()).thenReturn(userInfo);
    5. SageTax sageTax = new SageTax();
    6. sageTax.setEntryId(webContext.getUserInfo().getGlobalUserId());
    7. sageTax.setEntryDatetime(commonService.getDbTimestamp());
    8. sageTax.setTaxRate(BigDecimal.valueOf(0.011));
    9. sageTax.setTaxIdCode("test");
    10. sageTax.setCountryCode("CA");
    11. sageTax.setTaxCode("qqq");
    12. Mockito.when(sageTaxRepository.save(sageTax)).thenThrow(new Exception());
    13. Mockito.when(sageTaxService.addSageTax(sageTaxVO)).thenThrow(new Exception());
    14. }
  • 完善业务代码

总结和心得
  • 测试用例就是设计,因为每一个测试用例就是一个小的业务场景,大的业务也是由小的业务累积起来的。
  • TDD 要求开发人员按照测试,开发,重构,测试,开发,重构。。。。的过程来工作,一点一滴的完成设计。
  • 推翻了瀑布式的开发(先写功能代码,遇到编译错误的地方,就直接Debug项目,然后让其编译通过),站在用户的角度上进行工作。
  • 完善的安全网,不用担心重构代码的时候出错。
小技巧

通常写完测试用例,我们都需要看一下我们代码的覆盖率,通常市面上常用的工具是SonarQube,但是我们的IDEA也可以看到我们代码覆盖率。如下:

  • 选中xxxxTest.java,右键Run “xxxxTest.java” with Coverage。
  • 查看覆盖率,通常来说90%覆盖就好了。
    在这里插入图片描述
    在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,171人围观)

还没有评论,来说两句吧...

相关阅读

    相关 测试驱动开发(TDD)理论基础

    开始理论介绍之前,先思考一个问题:**软件开发中最重要的是什么?** * 可能有的小伙伴就会说:良好的数据库设计,一个健壮可扩展的架构,规范的编码风格,设计文档等。...

    相关 TDD测试驱动开发

    TDD(Test-Driven Development)是敏捷开发中的一项核心实践和技术,也是一种设计方法论,其基本思想是:在明确要开发某个功能后,在开发功能代码之前,