有没有一种方法可以使用Jasmine监视整个实例?

5
我有一个复杂的JavaScript类,其中包含许多函数。如果在非生产环境下调用这些函数,则会抛出异常。在我的测试中,我需要将该类的模拟实例传递给另一个类的构造函数,但我不希望实际调用该类的任何复杂函数。我想要的是一个伪造对象,它具有复杂类的所有函数和属性,但对于所有函数只是jasmine间谍,什么也不做。
基本上,我想能够执行以下操作:
var fakeComplexClass = createFakeObject(ComplexClass);

var testInstanceOfSimpleClass = new SimpleClass( fakeComplexClass);

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

我可以这样做:

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

但是我有很多功能,而且我需要测试几个不同的复杂类,所以我需要一种简单的方法来监视类中的每个函数。
Jasmine确实有createSpyObj,但它要求您传递一个函数数组。如果我从复杂类中添加或删除函数,我不想在我的测试中维护该数组,因此我希望能够仅对所有存在的函数进行监视。
提前感谢您的帮助。
2个回答

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());

lib:

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方法...

0

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

var stub = sinon.stub(obj); 桩化了对象的所有方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接