孙继峰
  • 1
  • 新人请关照

TDD 实践中的疑惑

个人初期在项目中开始实践 TDD, 遇到个问题.

写测试时就会难免去关注他的实现. 比如写一个 Service 方法的测试用例时, 就要知道这个 Service 会依赖哪些 DAO 的哪些方法, 这个 DAO 方法会有什么样的返回, 然后才能去 mock DAO 的行为, 最后完成 Service 的测试用例. 写这个测试用例, 我就不得不去关注他的实现.

不知道我的姿势是哪里错了, 还请大家指教.

阅读 802
评论 1月20日提问
    3 个回答
    krun
    • 6.2k

    你把 DAO.getXXX 简单得看做一次取数据的操作 AnotherService.getXXX 呗.

    DAO 的本意就是屏蔽数据来源,它后边是数据库还是缓存还是一个其他应用的调用接口都无所谓,只需要知道它能给你数据就行了.

    那么回过头来,你这里需要什么数据,就 Mock 出这样的数据,写实现的时候再考虑这个数据需不需要更丰富(比如不再只返回一个简单映射的 DTO 而是一个完整的 Entity).

    只要你到时候 DAO 里的实现能产出要求的数据即可.

    如果你觉得老是要纠结实现,那么考虑一下这样搞:

    在单测里建一个接口(interface),里面只有这次单测涉及到的数据获取方法.

    为这个接口生成一个 mock 实例,然后注入到要测试的 service 里.

    以后写实现的时候,实现出这个接口里的方法即可.

    这样你的测试就跟实现分离了:测试仅用于规范.


    单测也不是说写了之后就不会动,先把逻辑理顺,后面调用的方法不一样那单测里也跟着改呗.

    评论 赞赏 1月20日

      "写测试时就会难免去关注他的实现."

      写测试之前不需要关注也不应该关注实现,你只需要你测试这个主体的输入输出是什么就可以了。你的想法有点走偏,你肯定是先设计好这个方法用来干嘛,然后需要传什么参数进去,然后会返回什么东西出来,然后将这个输入输出写成测试用例,最后再去想具体的实现。

      评论 赞赏 1月20日
        孙继峰
        • 1
        • 新人请关照

        感谢各位大佬的指点, 我发现我的问题了

        写实现的时候再考虑这个数据需不需要更丰富(比如不再只返回一个简单映射的 DTO 而是一个完整的 Entity).

        你只需要你测试这个主体的输入输出是什么就可以了

        我在写测试的时候还不够明确这个方法要干嘛, 即便是列出了各个 case, 但是现在细想一下这个 case 的粒度还是有些大, 还可以进一步细化.

        评论 赞赏 1月21日
          撰写回答

          登录后参与交流、获取后续更新提醒