关于单元测试,我们需要知道什么?- 术语辨析篇

栏目: 编程工具 · 发布时间: 5年前

内容简介:单元测试期间, 被测单元会存在一些外部依赖的情况。而单测中我们更加注重被测对象自身的功能和行为,以及与外部依赖的交互行为,比如是否调用,调用中参数,调用的次数和顺序以及返回的结果或发生的异常等,并不需要关注外部依赖的具体细节。当然你页可以选择这两部分一起测试,可大声念一遍我们的术语:「单元测试」。这样是否已经和我们测试的原则相违背了,可缺失被测单元再缺失外部依赖的情况下,测试是不能正常进行的,我们陷入了两难境界,是否要继续遵守我们的原则?

单元测试期间, 被测单元会存在一些外部依赖的情况。

而单测中我们更加注重被测对象自身的功能和行为,以及与外部依赖的交互行为,比如是否调用,调用中参数,调用的次数和顺序以及返回的结果或发生的异常等,并不需要关注外部依赖的具体细节。

当然你页可以选择这两部分一起测试,可大声念一遍我们的术语:「单元测试」。这样是否已经和我们测试的原则相违背了,可缺失被测单元再缺失外部依赖的情况下,测试是不能正常进行的,我们陷入了两难境界,是否要继续遵守我们的原则?

为了让我们够能贯彻我们原则,出现了stub 和 mock 此类对象,其功能就是代替外部依赖,从而满足模拟真实场景,帮助我们的单元测试顺利进行。

那如何分辨那些是 stub 和 mock 呢?接下来们来辨析一下这两个概念。

Stub v.s Mock

相同目的

stub 和 mock 对象的出现,其作用都是代替外部依赖,帮助我们顺利进行单元测试。

不同生命周期

Test lifecycle with stubs: Setup - Prepare object that is being tested and its stubs collaborators. Exercise - Test the functionality. Verify state - Use asserts to check object's state. Teardown - Clean up resources.
Test lifecycle with mocks: Setup data - Prepare object that is being tested. Setup expectations - Prepare expectations in mock that is being used by primary object. Exercise - Test the functionality. Verify expectations - Verify that correct methods has been invoked in mock. Verify state - Use asserts to check object's state. Teardown - Clean up resources.

stub 和 mock 在测试的生命周期中表现不同,stub 协助被测单元进行 自身的功能 的校验,mock 更多是测试 被测单元的行为 是否符合预期,且自身在 被测单元行为 触发后进行验证。

看似说的比较玄乎,我们来看看对应不同类型下的代码段:

//产品代码
function A(b) {
    this.num = 0;
    this._b = b;
}
A.prototype.run = function () {
    this.num = this._b.getNum();
};

//测试代码
describe("测试A类的run方法", function () {
    it("获得数字", function () {
        var stub_B = {  //B类的桩
            getNum: function(){
                return 1;
            }
        };

        var a = new A(stub_B); //注入桩
        a.run();

        expect(a.num).toEqual(1);
    });
});
复制代码
//产品代码
function A(b) {
    this.num = 0;
    this._b = b;
}
A.prototype.run = function () {
    this.num = this._b.getNum(2);
};

//测试代码(Mock为伪代码)
describe("测试A类的run方法", function () {
    it("获得数字", function () {
        var mockB = Mock.createMock({
            getNum: function(){}
        }); //如果B类存在的话,也可以直接传入B的原型:var mockB = Mock.createMock(B.prototype);
        Mock.expect(mockB.getNum, 2).return(1).times(1);

        var a = new A(mockB);
        a.run();

        expect(a.num).toEqual(1);
        Mock.verify();  //验证期望的行为发生:mockB的getNum传入的参数为2;调用了1次mockB.getNum
    });
});
复制代码

看代码 mock 好像比 stub 更加高级,因为 mock 可以再模拟真实环境下,协助被测单元进行测试自身功能,并且对于被测单元的对外部的行为同时进行测试,所以感觉是高级一些。

现状

实际情况下,我们编写的代码段更多是符合 stub 流程中的测试。可表现形式上,mock流程代码不是更高级吗?为什么现实使用中,我们并没有使用 mock 流程中的代码?

因为在通常情况下,我们使用的 mock 是退化的mock,从而是的 mock 流程和 stub 流程在测试使用上行为一致。其实我们是把 mock 当做了 stub 进行使用,其主要区别是 mock 创建时期就没有添加对应的后续期望,导致后期也用不着进行验证。就像这样:

//产品代码
function A(b) {
    this.num = 0;
    this._b = b;
}
A.prototype.run = function () {
    this.num = this._b.getNum(2);
};

//测试代码(Mock为伪代码)
describe("测试A类的run方法", function () {
    it("获得数字", function () {
        var mockB = Mock.createMock({
            getNum: function(){}
        }); //如果B类存在的话,也可以直接传入B的原型:var mockB = Mock.createMock(B.prototype);
        Mock.expect(mockB.getNum).return(1);    //只指定返回值,没有期望的参数或期望调用的次数。因此不用verify来验证了!

        var a = new A(mockB);
        a.run();

        expect(a.num).toEqual(1);
    });
});
复制代码

为什么我们出现这样情况?很有可能是因为在日常使用中,我们对两者的概念边界都比较模糊,而且开发中经常涉及 mock 数据等术语,更容易干扰我们在单元测试语境下对 mock 的定义。所以在Jest社区中因为区分命名也进行过对应的讨论。 Rename jest.mock to jest.stub

PS: 以上案例代码摘自参考文献。

参考文献

  1. 我对Stub和Mock的理解
  2. 浅谈mock和stub
  3. 极客时间-软件测试52讲-什么是单元测试?如何做好单元测试?

以上所述就是小编给大家介绍的《关于单元测试,我们需要知道什么?- 术语辨析篇》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Developing Large Web Applications

Developing Large Web Applications

Kyle Loudon / Yahoo Press / 2010-3-15 / USD 34.99

As web applications grow, so do the challenges. These applications need to live up to demanding performance requirements, and be reliable around the clock every day of the year. And they need to withs......一起来看看 《Developing Large Web Applications》 这本书的介绍吧!

html转js在线工具
html转js在线工具

html转js在线工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具