如何在单元测试之间重置requirejs模块

时间:2015-01-18 15:25:09

标签: javascript unit-testing requirejs karma-runner

我有一个JavaScript项目,我想观察TDD方法。我为此选择了karma框架和requirejs库,并遵循了karma docs here中演示的示例。

有一个单元测试文件的示例,即:

define(['app', 'jquery', 'underscore'], function(App, $, _) {

    describe('just checking', function() {

        it('works for app', function() {
            var el = $('<div></div>');

            var app = new App(el);
            app.render();

            expect(el.text()).toEqual('require.js up and running');
        });

        it('works for underscore', function() {
            // just checking that _ works
            expect(_.size([1,2,3])).toEqual(3);
        });

    });

});

此方法的主要问题是无法清除每个测试的App模块。因此,如果在it次调用中应用程序中有一些更改(如关闭变量更改等),那么它们可能会影响其他it调用。

有人可以就此提出建议吗?这些都是如此受欢迎的工具,我无法相信没有人遇到过这样的情况。

所以,概括一下这个问题,我想问一下这些更具体的问题的答案:

  • 有没有办法在requirejs中“重置”(清除)模块? (实际上,我认为没有这样的方法,除了再次重新加载所有模块
  • 有没有更好的方法来运行karma和requirejs,这样模块就没有其他测试(it函数调用)的遗留(副作用)?

2 个答案:

答案 0 :(得分:3)

在谷歌的帮助下,我找到了解决方案。我不能说它是理想的,但它至少起作用,并且在每个测试中,所需的模块处于 pristine 状态。

首先,需要拥有这样的main.js测试文件,它几乎与docs中的相同,除了测试未被定义为模块并且不作为依赖项包含在内:

require.config({file
    baseUrl: '/base',
    paths: {},
    shim: {},
    deps: [],
    callback: window.__karma__.start
});

在主要的业力配置必须存在这个(一个需要调整自己的路径)

files: [
    {pattern: 'src/**/*.js', included: false},
    'tests/unit/**/*.js'
],

在测试中,我们利用 jasmine 异步测试功能和 requirejs.undef 方法来“清除”模块(将重置加载器的内部状态忘记模块的先前定义,正如docs中所述。

这个方法有一个含义,它不会重置已经加载并依赖于重置模块的其他模块,但这不应该是一个问题,如果以正确的方式编写测试,那就是他测试只有一个模块(并且可能是一些父模块,子项从中继承了某些行为),因此在{1}上使用几个模块并不困难。

undef

我已经检查了这一点,在describe('Some/Module tests', function() { 'use strict' var M beforeEach(function(done) { requirejs.undef('src/Some/GParentModule') requirejs.undef('src/Some/ParentModule') requirejs.undef('src/Some/Module') require(['src/Some/Module'], function(m) { M = m done() }) }) it('some description', function() { var i = 0 for (var prop in M) { i++ } expect(i).toEqual(1) expect(prop).toEqual('init') expect(M.init).toEqual(jasmine.any(Function)) }) }) 次调用之间,对模块的更改不会持续存在,所以我想,使用这种方法是安全的。

感谢大家的帮助,如果有人有更好的方法,请在这里回答。

答案 1 :(得分:2)

  
      
  • 有没有办法重置&#34;在requirejs中的(清除)模块?
  •   

您可以使用requirejs.undef(),但文档中提到了一些问题。据我所知,没有任何电话可以用来说“卸载这个模块及其依赖的所有内容&#34;”,在复杂的应用程序中可能需要它。

  
      
  • 有没有更好的方法来运行karma和requirejs,这样模块就没有其他测试(它的函数调用)的剩余(副作用)呢?
  •   

更好的方法是设计应用程序,使状态与您实例化的对象相关联,而不是与模块本身相关联。这就是我在我的大型应用程序的测试套件中所做的。 beforeEach挂钩重置需要重置的内容,并为每次测试重新实例化应用程序。