如何对其输入完全不改变功能行为的功能进行单元测试?

时间:2019-01-29 06:32:58

标签: java unit-testing

有时在考虑单元测试时遇到麻烦。让我们看一下这种情况:

@POST
    @Path("/search")
    public Response searchSelections(SearchRequestDto searchRequestDto,
        @BeanParam ScrollableDto scrollableDto) {
        Scrollable scrollable = Scrollable.getScrollable(scrollableDto);
        Page<SelectionDto> selectionDtos =
            selectionService.search(searchRequestDto, scrollable);
        return Response.ok(selectionDtos).build();
    }

因此,在此Controller单元测试(不讨论集成)中,从业务角度来看,我期望这些:

  1. 如果searchRequestDto为null,则不应用任何过滤器,我希望所有 实体。
  2. 如果scrollableDto为null,则不应用分页,我 期待所有实体。
  3. 如果搜索请求未找到任何内容, scrollable是否为null,如果在数据库中找不到任何内容,我希望 带有HTTP.OK的空列表的页面对象。

那么如何在这里进行单元测试?我上面定义的所有数字均由另一类负责。因此,我所能做的就是嘲笑它们,而无需在我在此处测试的searchSelections()函数中进行任何检查。例如;

如果scrollableDto为null(上面的数字2):

  • 上面我的函数的第一行->我不在乎,因为它是已经过单元测试的Scrollable.getScrollable函数的责任。
  • 上面我的函数的第二行->从上面可以滚动显示响应。因此,此可滚动对象是selectionService.search的参数,我也不在乎,因为它已经过单元测试。因此,scrollableDto为null或不为null会影响我上一行只是在嘲笑的行,而不会影响我当前的函数状态。
  • 函数上面的最后一行->我应该从先前的模拟中返回selectionDtos。现在,我的2号单元测试方案scrollableDto = null对我来说没有意义,因为它是模拟的,结果是模拟的。

与其他单元测试方案相同。我该怎么想,当我的参数不改变被测函数的状态时,它只会影响我已经嘲笑的另一个经过单元测试的函数状态?

(我不想验证没有任何有价值的输出的方法调用,它总是会增加我们的测试成本,如果函数重构但其输出相同,则应该始终对其进行更新。还需要更新我们的测试,如果验证了函数调用/参数,则需要花费一些时间,数据库调用等某些情况除外)

2 个答案:

答案 0 :(得分:0)

那么您为什么坚持对这种方法进行单元测试?您只需要进行1或2个高级(称为集成)测试,即可检查从Controller到DB的所有功能是否协同工作。

测试会带来额外的维护成本,因此,如果您可以省略它们(在这种情况下可以),那就太好了。

答案 1 :(得分:0)

您有两次数据转换

Scrollable scrollable = Scrollable.getScrollable(scrollableDto);

return Response.ok(selectionDtos).build();

您有一个依赖项:

Page<SelectionDto> selectionDtos = selectionService.search(searchRequestDto, scrollable);
  • 因此,安排阶段应以Scrollable.getScrollable(scrollableDto)的结果返回选择页面的方式对依赖项进行存根。
  • 行为阶段应调用情景2中的约束searchSelections
  • 断言阶段应断言响应完全包含您在安排阶段中存根的选择页面

此测试可能比集成测试快。但是,如果您打算以综合方式测试此方法,则也可以跳过此测试。