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

发表于:2020-3-13 11:06  作者:风月同天测试人   来源:软件测试那些事

字体: | 上一篇 | 下一篇 |我要投稿 | 推荐标签: 软件测试技术

  首先问一个问题,在接口测试中,验证被测接口的返回值是否符合预期是不是就够了呢?
  场景
  转账是银行等金融系统中常见的一个场景。在在最近的一个针对转账服务的单元测试中,笔者就遇到了上述问题。一个极端简化的转账申请如下图:
  在一个B端用户通过转账服务接口发起转账申请后,转账服务接口在完成发起转账申请的过程中,在完成各项合法性校验,确定可以发起转账时,会从外部流水号服务那里申请到一个全局唯一且单调递增的流水号,该流水号将作为转账申请提交成功的返回值向申请方返回。同时,该流水号将作为转账申请记录的一部分,写入后台数据库等待后续审核。
  从上述介绍中,我们得以了解到,这里的转账服务接口只是完成了申请的接收工作。转账申请需要后续被人工审核后才能完成实际的转账。
  实现伪代码
   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();
  }
  }
  以上是一个极简的代码实现逻辑,完成了申请单检查、流水号获取、数据库保存以及接口返回。
  第一个单元测试- 请求/返回
   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);
  }
  }
  第一个用例首先验证了接口的返回值。
  第二个单元测试-写库
   @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进行对象的多个属性的断言。

上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。

评 论

论坛新帖

顶部 底部


建议使用IE 6.0以上浏览器,800×600以上分辨率,法律顾问:上海瀛东律师事务所 张楠律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2020, 沪ICP备05003035号
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪公网安备 31010102002173号

51Testing官方微信

51Testing官方微博

扫一扫 测试知识全知道