javascript - 使用 Jasmine 监视整个实例的任何方法

标签 javascript unit-testing jasmine

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

基本上我希望能够做到

var fakeComplexClass = createFakeObject(ComplexClass);

var testInstanceOfSimpleClass = new SimpleClass( fakeComplexClass);

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

我可以做类似的事情

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

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

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

提前致谢。

最佳答案

我创建了一个与 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 方法...

关于javascript - 使用 Jasmine 监视整个实例的任何方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8994233/

相关文章:

javascript - 如何使用 JavaScript 更新 iframe

python - Django 单元测试 - 如何断言自定义管理器调用 UserManager.create_user 方法?

c++ - CMake:尝试将链接库添加到未在此目录中构建的目标

typescript - 试图让 Jasmine 与 Webpack 一起工作

javascript - 引用错误 : module is not defined in jasmine

javascript - 比较文件中的图像和从 Canvas 创建的图像

javascript - 如何使用 jquery 将文本从一个页面复制并粘贴到另一个页面?

javascript - 任务从未定义 : Moving from gulpV3 to gulpV4

javascript - jQuery 窗口宽度不等于 CSS 的窗口宽度

java - 在 JUnit 测试中是否可以检查方法 System.out.println()