前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何在单元测试中对写数据库进行测试?

如何在单元测试中对写数据库进行测试?

作者头像
Antony
发布2020-12-01 18:04:07
3.6K0
发布2020-12-01 18:04:07
举报

首先问一个问题,在接口测试中,验证被测接口的返回值是否符合预期是不是就够了呢?

场景

转账是银行等金融系统中常见的一个场景。在在最近的一个针对转账服务的单元测试中,笔者就遇到了上述问题。一个极端简化的转账申请如下图:

在一个B端用户通过转账服务接口发起转账申请后,转账服务接口在完成发起转账申请的过程中,在完成各项合法性校验,确定可以发起转账时,会从外部流水号服务那里申请到一个全局唯一且单调递增的流水号,该流水号将作为转账申请提交成功的返回值向申请方返回。同时,该流水号将作为转账申请记录的一部分,写入后台数据库等待后续审核。

从上述介绍中,我们得以了解到,这里的转账服务接口只是完成了申请的接收工作。转账申请需要后续被人工审核后才能完成实际的转账。

实现伪代码

代码语言:javascript
复制
public class EntryRepository {
...
    public void save(Entity entity) {
        System.out.println(entity.getFlowNo);
    }
}

@Service
public class EntryService  throws Exception{
    @Autowired
    private EntryRepository entryReposity;
    
    @Autowired
    private FlowNoService flowNoService;
    
@Transactional
    public String submit(Entity entity) {
        validEntity(entity);
    entity.setFlowNo(flowNoService.getNextFlowNo()); //流水号
       entity.setStatus("SUBMITTED"); //已提交
        entryReposity.save(entity);
        return entity.getFlowNo();
    }
}

以上是一个极简的代码实现逻辑,完成了申请单检查、流水号获取、数据库保存以及接口返回。

第一个单元测试- 请求/返回

代码语言:javascript
复制
public class EntryServiceTest {
@InjectMocks
private EntryService entryService;
@Mock
private EntryRepository entryReposity;
@Mock
private FlowNoService flowNoService;
@Test
public void shouldReturnFlowNo(){
Entity entity= new entity;
entity.setAmount("一个亿");
String flowNo="20200307000001";
Mockito.when(flowNoService.getNextFlowNo()).thenReturn(flowNo);
assertThat(entryService.submit(entity)).isEqualTo(flowNo);
}
}

第一个用例首先验证了接口的返回值。

第二个单元测试-写库

代码语言:javascript
复制
@Captor
private ArgumentCaptor<Entity> captor;
@Test
public void shouldCapture() {

    Entity entity= new entity;
    entity.setAmount("一个亿");
    String flowNo="20200307000001";
    Mockito.when(flowNoService.getNextFlowNo()).thenReturn(flowNo);
    Mockito.verify(entryReposity,times(1)).save(captor.capture());
    Entity captured= captor.getValue();
        
    Entity expected= new Entity();
        expected.setFlowNo(flowNo);
        expected.setStatus("SUBMITTED");
    assertThat(captured).isEqualToComparingOnlyGivenFields(expected,"flowNo","status");

}
}

在之前的测试用例类中,我们再添加第二个单元测试用例,来验证数据库写库的数据是否符合预期结果。

第三个用例 -- 两笔申请?

如何对两笔申请进行单元测试,Mock又如何写?这个就留给读者自行练习了。

如果不是写库,而是通过MQ对外发布?又如何进行测试呢?

小结

本案例演示了如何使用Mockito提供的Capture特性来验证方法的传参,同时也展示了如何使用AssertJ进行对象的多个属性的断言。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-03-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 软件测试那些事 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 场景
  • 实现伪代码
  • 第一个单元测试- 请求/返回
  • 第二个单元测试-写库
  • 第三个用例 -- 两笔申请?
  • 小结
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档