【问题标题】:Any way to spy on an entire instance with Jasmine使用 Jasmine 监视整个实例的任何方式
【发布时间】:2012-02-18 03:16:36
【问题描述】:

我有一个复杂的 javascript 类,它有很多函数,如果在生产环境之外调用它们中的许多会抛出异常。我需要在我的测试中将此类的模拟实例传递给另一个类的构造函数,但是我不希望实际调用任何复杂的类函数。我想做的是有一个假对象,它具有复杂类的所有功能和属性,但所有功能都只是什么都不做的茉莉间谍。

基本上我希望能够做到

var fakeComplexClass = createFakeObject(ComplexClass);

var testInstanceOfSimpleClass = new SimpleClass( fakeComplexClass);

并确保如果testInstanceOfSimpleClass 调用任何fakeComplexClass 函数,它们将是间谍,因此不会使我的测试崩溃。

我可以做类似的事情

var fakeComplexClass = { function1() {};, function2() {}; ... } 

但是有很多函数,我需要测试几个不同的复杂类,所以我需要一个简单的方法来基本上监视类中的每个函数。\

Jasmine 确实有 createSpyObj,但它要求您向其传递一组函数。如果我碰巧在复杂类中添加或删除函数,我不想在测试中维护该数组,所以我想要一些可以监视那里的每个函数的东西。

提前致谢。

【问题讨论】:

    标签: javascript unit-testing jasmine


    【解决方案1】:

    我创建了一个小库,它与 jasmine-node 一起使用。

    用法:

        var MyClass = function (param) {
            this.initialize(param);
        };
        MyClass.prototype.initialize = function (param) {
            if (param != "expectedParam")
                throw new TypeError();
        };
    
        var mock1 = jasmine.createStub(MyClass, ["*"]);
        expect(mock1.constructor).toHaveBeenCalled();
        expect(mock1.initialize).not.toHaveBeenCalled();
    
        var mock2 = jasmine.createStub(MyClass, ["initialize"], ["expectedParam"]);
        expect(mock2.initialize).toHaveBeenCalled();
        mock2.initialize.andCallThrough();
        expect(mock2.initialize).toThrow(new TypeError());
    

    库:

    jasmine.createStub = function (cls, methods, args) {
        if (!(cls instanceof Function))
            throw new TypeError("Invalid class param.");
    
        var mockClass = function () {
            this.constructor.apply(this, args || []);
        };
    
        mockClass.prototype = Object.create(cls.prototype);
        mockClass.prototype.constructor = cls;
    
        var wrap = function (method) {
            if (!mockClass.prototype[method] instanceof Function)
                throw new TypeError("Cannot mock " + method + " it's not a function.");
            jasmine.getEnv().currentSpec.spyOn(mockClass.prototype, method);
        };
    
        if (methods) {
            if (!(methods instanceof Array))
                methods = [methods];
            if (methods.length == 1 && methods[0] == "*")
                for (var property in mockClass.prototype) {
                    if (mockClass.prototype[property] instanceof Function)
                        wrap(property);
                }
            else
                for (var i = 0; i < methods.length; ++i) {
                    var method = methods[i];
                    wrap(method);
                }
        }
    
        return new mockClass();
    };
    

    我认为这一行不适用于浏览器中的 jasmine,但没有对其进行测试:

    jasmine.getEnv().currentSpec.spyOn(mockClass.prototype, method);
    

    不知何故,我的 jasmine-node 没有 jasmine.spyOn 方法...

    【讨论】:

      【解决方案2】:

      看看SinonJS,它让你stub一个完整的对象:

      var stub = sinon.stub(obj); 存根对象的所有方法。

      【讨论】:

        猜你喜欢
        • 2019-03-31
        • 1970-01-01
        • 2021-02-04
        • 2017-06-16
        • 1970-01-01
        • 2013-01-09
        • 1970-01-01
        • 2018-04-20
        相关资源
        最近更新 更多