8

我有很多几乎相同的测试。为了 DRY 和可扫描性,我想将测试抽象为一个函数,然后用几个参数调用该函数。然后该函数将调用it该规范并将其添加到套件中。

它似乎工作,除了规范没有以与其他规范相同的方式运行,并且beforeEach没有在公共函数中定义的规范之前调用。

define(['modules/MyModule','jasmine/jasmine'], function(MyModule) {

    describe('myModule', function() {

        function commonTests(params) {
            it('should pass this test OK', function() {
                expect(true).toBe(true);
            });

            it('should fail because module is undefined', function() {
                expect(module[params.method]()).toBe('whatever');
            });
        }

        var module;

        beforeEach(function() {
            module = new MyModule();
        });

        describe('#function1', function() {
            commonTests({
                method: 'function1'
            });
        });

        describe('#function2', function() {
            commonTests({
                method: 'function2'
            });
        });

    });

});

有什么办法可以做到这一点并保持 and 的功能beforeEachafterEach

更新:

看来我的例子错了,对不起。这是失败的情况:

define(['modules/MyModule'], function(MyModule) {

    function commonTests(params) {
        it('will fail because params.module is undefined', function() {
            expect(typeof params.module).toBe('object');
            expect(typeof params.module[params.method]).toBe('function');
        });

        it('has a few tests in here', function() {
            expect(true).toBe(true);
        });
    }


    describe('MyModule', function() {

        var module;

        beforeEach(function() {
            module = new MyModule();
        });

        describe('#function1', function() {
            commonTests({
                module: module,
                method: 'function1'
            });
        });

        describe('#function2', function() {
            commonTests({
                module: module,
                method: 'function2'
            });
        });

    });
});

我认为它失败了,因为值module被保留为调用的一部分,而不是像第一个示例commonTests中那样始终使用当前值。module当我到达那里时,我会发布我的解决方案......

4

2 回答 2

5

感谢 Andreas 指出我的第一个示例确实有效!我使用的最终解决方案非常相似:

define(['modules/MyModule'], function(MyModule) {

    var module;

    function commonTests(params) {
        it('will not fail because module is shared', function() {
            expect(typeof module).toBe('object');
            expect(typeof module[params.method]).toBe('function');
        });

        it('has a few tests in here', function() {
            expect(true).toBe(true);
        });
    }


    describe('MyModule', function() {

        beforeEach(function() {
            module = new MyModule();
        });

        describe('#function1', function() {
            commonTests({
                method: 'function1'
            });
        });

        describe('#function2', function() {
            commonTests({
                method: 'function2'
            });
        });

    });
});

尽管如果您需要能够module作为参数传递给commonTests您,则必须采用稍微不同的方法并为每个it块具有不同的功能:

define(['modules/MyModule'], function(MyModule) {

    var module;

    function commonTest1(params) {
        expect(typeof module).toBe('object');
        expect(typeof module[params.method]).toBe('function');
    }

    function commonTest2(params) {
        expect(true).toBe(true);
    }


    describe('MyModule', function() {

        beforeEach(function() {
            module = new MyModule();
        });

        describe('#function1', function() {

            it('will not fail because module is shared', function() {
                commonTest1({ method: 'function1' });
            });

            it('has a few tests in here', function() {
                commonTest2({ method: 'function1' });
            });

        });

        describe('#function2', function() {

            it('will not fail because module is shared', function() {
                commonTest1({ method: 'function2' });
            });

            it('has a few tests in here', function() {
                commonTest2({ method: 'function2' });
            });

        });

    });
});

这样,包含公共测试的函数的执行将延迟到 beforeEach 运行其回调之后。

于 2012-11-01T14:39:29.857 回答
0

是的,这种情况对我们来说很好。我们使用 chutzpah 在我们的门控签入中运行测试,如果没有这些afterEach功能,我们的测试将失败。

但这define条线看起来像require.js。我们有几个问题......我想这MyModuleundefined或没有按预期定义。您是否尝试在beforeEach方法中设置断点以查看它是否被调用以及MyModule具有什么值?你怎么称呼测试?

当我在没有该define行的情况下运行您的代码时,该beforeEach函数被称为 4x - 正如预期的那样。顺便说一句,我使用 chutzpah.console.exe 来调用测试。

编辑:

是的,现在我可以在我的电脑上重现这个问题了。这对我来说更清楚。一开始module是未定义的,因为每个变量首先是未定义的。beforeEach然后你使用和注册你的功能在茉莉花中describe。Jasmine 从评估开始

function() {
    commonTests({
        module: module,
        method: 'function1'
    });
}

这是传递给第一个describe。在这一行,module: moduleJS 复制了对新对象属性的引用和到目前为止的this 引用。当回调被调用时,它会将 的引用更改为正确的值,但错误的引用已被复制...var modulemoduleundefinedbeforeEachvar module

我试图移到var module上面function commonTests并在测试中使用该变量,而不是params.module它们按预期通过。我不知道这是否是您环境中的一个选项,但我希望它有所帮助。

问候,安德烈亚斯

于 2012-10-31T22:11:24.980 回答