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

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/wangchengming1/article/details/101454754

在上一篇文章中用一个计算长方形面积的小例子介绍了如何使用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.编写测试用例
    @InjectMocks
    SageTaxService sageTaxService = new SageTaxServiceImpl();

    @Mock
    SageTaxRepository sageTaxRepository;

    @Mock
    CommonService commonService;

    @Mock
    WebContext webContext;

	@Test
    public void test_add_sage_tax() {
        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(999);
        Mockito.when(webContext.getUserInfo()).thenReturn(userInfo);

        SageTax sageTax = new SageTax();
        sageTax.setEntryId(webContext.getUserInfo().getGlobalUserId());
        sageTax.setEntryDatetime(commonService.getDbTimestamp());
        sageTax.setTaxRate(BigDecimal.valueOf(0.011));
        sageTax.setTaxIdCode("test");
        sageTax.setCountryCode("CA");
        sageTax.setTaxCode("qqq");

        Mockito.when(sageTaxRepository.save(sageTax)).thenReturn(sageTax);
        Assert.assertNotNull(sageTaxService.addSageTax(sageTax));
    }
2.运行测试用例

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

3.编写业务代码
	@Override
    public Boolean addSageTax(SageTax sageTaxVO) {
        List<SageTax> sageTaxList = Lists.newArrayList();
        if (sageTaxVO.getCountryCode() != null && sageTaxVO.getTaxCode() != null) {
        	// countryCode and taxCode is unique key
            sageTaxList = getSageTax(sageTaxVO.getCountryCode(), sageTaxVO.getTaxCode());
        }
        if (sageTaxList.size() > 0) {
        	// if has data in DB, return false
            return false;
        }
        SageTax sageTax = new SageTax();
        sageTax.setEntryId(webContext.getUserInfo().getGlobalUserId());
        sageTax.setEntryDatetime(commonService.getDbTimestamp());
        sageTax.setTaxId(sageTaxVO.getTaxId());
        sageTax.setTaxIdCode(sageTaxVO.getTaxIdCode());
        sageTax.setCountryCode(sageTaxVO.getCountryCode());
        sageTax.setTaxCode(sageTaxVO.getTaxCode());
        sageTax.setTaxRate(sageTaxVO.getTaxRate());
        sageTaxRepository.save(sageTax);
        return true;
    }
4.运行测试用例,然后看到测试用例通过了
5.对代码查缺补漏,进行重构
  • 补充测试用例,因为可能在保存的时候会出错,所以新增一个case用来覆盖抛出exception的情况。
	@Test(expectedExceptions = Exception.class)
    public void test_add_sage_tax_with_exception() {
  		UserInfo userInfo = new UserInfo();
        userInfo.setUserId(999);
        Mockito.when(webContext.getUserInfo()).thenReturn(userInfo);

        SageTax sageTax = new SageTax();
        sageTax.setEntryId(webContext.getUserInfo().getGlobalUserId());
        sageTax.setEntryDatetime(commonService.getDbTimestamp());
        sageTax.setTaxRate(BigDecimal.valueOf(0.011));
        sageTax.setTaxIdCode("test");
        sageTax.setCountryCode("CA");
        sageTax.setTaxCode("qqq");
        
        Mockito.when(sageTaxRepository.save(sageTax)).thenThrow(new Exception());
        Mockito.when(sageTaxService.addSageTax(sageTaxVO)).thenThrow(new Exception());
    }
  • 完善业务代码
总结和心得
  • 测试用例就是设计,因为每一个测试用例就是一个小的业务场景,大的业务也是由小的业务累积起来的。
  • TDD 要求开发人员按照测试,开发,重构,测试,开发,重构。。。。的过程来工作,一点一滴的完成设计。
  • 推翻了瀑布式的开发(先写功能代码,遇到编译错误的地方,就直接Debug项目,然后让其编译通过),站在用户的角度上进行工作。
  • 完善的安全网,不用担心重构代码的时候出错。
小技巧

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

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

猜你喜欢

转载自blog.csdn.net/wangchengming1/article/details/101454754
今日推荐