【问题标题】:Using actual object in Unit Test works but Sinon Mocked object does not in Javascript ES6在单元测试中使用实际对象有效,但在 Javascript ES6 中无法使用 Sinon 模拟对象
【发布时间】:2017-10-19 08:10:05
【问题描述】:

我在编写单元测试用例时尝试使用 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# 中使用过模拟。但是在那里我将模拟对象传递给了构造函数。不是实际的对象。
有人可以帮助我理解Sinon嘲笑这种行为的原因吗?

【问题讨论】:

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


    【解决方案1】:

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

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

    来自道格拉斯·克罗克福德:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-29
      • 1970-01-01
      • 2020-05-17
      • 2018-06-18
      • 2019-01-22
      相关资源
      最近更新 更多