使用单元测试中的实际对象,但Sinon Mocked对象不在Javascript ES6中

时间:2017-05-19 09:10:23

标签: javascript unit-testing ecmascript-6 mocking sinon

我在编写单元测试用例时尝试使用Sinon来模拟依赖项。我遇到了一些问题,但终于成功了。但它的工作方式对我来说似乎很奇怪。

Employee依赖于类Data,因此Data对象是依赖注入到类Employee的构造函数中。

以下是有效的代码:

class Data{
    getName(){
        return "Ram";
    }
}

class Employee{
    constructor(data){
        this._data = data;
    }

    getName(){
        return this._data.getName();
    }
}

describe('canary suite', function(){
    it('canary test', function(){

        var data = new Data();
        var mockData = sinon.mock(data);        
        mockData.expects('getName').returns('Raj');

        var emp = new Employee(data); //here is the deviation.

        expect(emp.getName()).equals('Raj');
        mockData.verify();
        mockData.restore();
    });
});

如果我在代码中更改此行:

var emp = new Employee(data);

var emp = new Employee(mockData);

它给出了这个错误:

  

TypeError:this._data.getName不是函数

之前我曾在C#中使用过mocks。但是我将模拟对象传递给构造函数。不是实际的对象 有人可以帮我理解Sinon嘲笑这种行为的原因吗?

1 个答案:

答案 0 :(得分:1)

在像C#这样的语言中,以及类型/接口和公共/私有范围,对象实例通常是不可变。这意味着将mock作为原始对象的类/接口的“空壳”创建更为常见。

Javascript最近才支持类和继承等,它的核心是Prototype-based语言。

来自Douglas Crockford:

  

你制作原型对象,然后......制作新实例。对象在JavaScript中是可变的,因此我们可以扩充新实例,为它们提供新的字段和方法。然后,这些可以作为更新对象的原型。我们不需要类来创建许多类似的对象......对象继承自对象。

这就是为什么在Javascript中模拟原始对象实例本身更有意义,以及为什么Sinon提供restore()来删除模拟行为。