我有一个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
调用。
有人可以就此提出建议吗?这些都是如此受欢迎的工具,我无法相信没有人遇到过这样的情况。
所以,概括一下这个问题,我想问一下这些更具体的问题的答案:
it
函数调用)的遗留(副作用)?答案 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
挂钩重置需要重置的内容,并为每次测试重新实例化应用程序。