我有很多测试几乎都是一样的。为了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'
});
});
});
});
有没有办法做到这一点并维护beforeEach
和afterEach
的功能?
更新:
看起来我的示例错了,抱歉。这是失败的情况:
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
的当前值。当我到达那里时,我会发布我的解决方案......
答案 0 :(得分: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运行其回调之后。
答案 1 :(得分:0)
afterEach
函数,我们的测试将失败。
但define
行看起来像require.js
。我们有几个问题......
我认为MyModule
是undefined
或未按预期定义。您是否尝试在beforeEach
方法中设置断点以查看它是否已被调用以及MyModule
具有什么值?你是怎么称呼考试的?
当我在没有define
行的情况下运行代码时,beforeEach
函数被调用4x - 正如预期的那样。顺便说一句,我使用chutzpah.console.exe来调用测试。
编辑:
是的,现在我可以在我的电脑上重现这个问题了。而且对我来说更清楚了。
在开头module
未定义,因为每个变量都是未定义的。然后使用beforeEach
和describe
在茉莉花中注册您的函数。 Jasmine从评估开始
function() {
commonTests({
module: module,
method: 'function1'
});
}
传递给第一个describe
。在第module: module
行,JS将var module
的引用复制到新对象属性module
,此引用到目前为止undefined
。调用beforeEach
回调后,它会将var module
的引用更改为正确的值,但错误的引用已被复制...
我尝试将var module
移到function commonTests
之上并在测试中使用该变量而不是params.module
,并且它们按预期传递。我不知道这是否适用于您的环境,但我希望它有所帮助。
电贺, 安德烈亚斯