《Unit Testing》2.1 伦敦学派如何做隔离

    技术2022-07-10  95

    针对单元测试的定义,主要有两种看法:

    经典学派。经典学派之所以经典,是因为这原本就是人们做单元测试和测试驱动开发的方式

    伦敦学派。伦敦学派扎根于伦敦的编程社区。

     

    单元测试的定义

    单元测试有很多定义,但是所有的定义都有三个重要的属性。单元测试是一个自动化测试,并且:

    验证一小段代码(或者叫一个单元)

    执行速度快

    使用隔离的方式进行

     

    而隔离的方式是经典学派和伦敦学派的根本区别所在。(我个人使用经典的方式)

     

    隔离问题,伦敦学派的做法

    以隔离的方式验证一段代码(一个单元)意味着什么?

    伦敦学派把它描述成将被测试系统(SUTSystem Under Test与它的协作者隔离开来。也就是说,如果一个 class 有依赖项或依赖其它的class,需要把这些依赖项都使用测试替身(test double来替换掉。

    测试替身(test double是一个外观和行为都与其对应的正式版本类似的对象,但它是一个简化版,它降低了复杂性并有助于测试。

     

    使用测试替身替换依赖项,如下图:

    这样做的好处有:

    如果测试失败,出问题的代码肯定是 SUT(被测试系统)。其它地方不会出现嫌疑,因为其邻居都被测试替身替换掉了。

    它能够拆分对象图,也就是沟通的类之间组成的网络。你可以把被测试类的直接依赖项替换掉,这样就不需要再处理依赖项的依赖项了,从而大大减少单元测试的准备工作。

    还有一个小的优点,它允许你引入项目范围内的指南:一次只测试一个类。这样的话就无需考虑代码覆盖率的问题了,因为如果建立一个类,那么就创建它对应的一个测试类。如下图:

      

    如何创建测试替身?

    首先看经典学派如何做单元测试:

    这里面 Customer 是被测试系统 SUT,而 Store 是它的协作者。

    在经典学派里,不使用测试替身替代依赖项。

     

    针对同一个类,伦敦学派是这样做单元测试的:

    这里我使用了Moqhttps://github.com/moq/moq4)框架。

    具体的说,我是用mock 这种东西替代了 Store。(而 mock 是测试替身的一种,现在知道这么多就行)。

    这里面 Mock<IStore> 就是 Store 的简化版:

    在传入特定参数时,HasEnoughInventory 方法会被指定返回 true false

    此外,也可以得到 RemoveInventory 被调用的次数,并将其用于验证。

    Processed: 0.034, SQL: 9