javascript 是否可以在函数内定义 Jasmine 规范并且仍然有 beforeEach 适用于它?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13139977/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it possible to define a Jasmine spec inside a function and still have beforeEach apply to it?
提问by Mark Stickley
I have a lot of tests which are virtually the same. In the interests of DRY and scanability I'd like to abstract the tests into a single function and then call that function with a few parameters. The function would then call it
and add the spec to the suite.
我有很多几乎相同的测试。为了 DRY 和可扫描性,我想将测试抽象为单个函数,然后使用几个参数调用该函数。然后该函数将调用it
规范并将其添加到套件中。
It seems to work, except the specs don't get run in the same way as the other specs and beforeEach
is not called before the specs defined in the common function.
它似乎有效,除了规范的运行方式与其他规范不同,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'
});
});
});
});
Is there any way of doing this and maintaining the functionality of beforeEach
and afterEach
?
是否有这样做的,维护的功能的任何方式beforeEach
和afterEach
?
UPDATE:
更新:
Looks like I got my example wrong, sorry. Here's the case that fails:
看起来我的例子错了,抱歉。这是失败的情况:
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'
});
});
});
});
I think it fails because the value of module
is preserved as part of the call to commonTests
instead of always using the current value of module
as in the first example. I'll post my solution when I get there...
我认为它失败了,因为 的值module
被保留为调用的一部分,commonTests
而不是module
像第一个示例中那样始终使用当前值。当我到达那里时,我会发布我的解决方案......
采纳答案by Mark Stickley
Thanks to Andreas for pointing out that my first example actually worked! The final solution I'm using is very similar:
感谢 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'
});
});
});
});
Although if you needed to have the ability to pass in module
as an argument to commonTests
you would have to take a slightly different approach and have a different function for each it
block:
尽管如果您需要能够将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' });
});
});
});
});
This way the executions of the functions containing the common tests is delayed until after beforeEach has run its callback.
这样,包含公共测试的函数的执行会延迟到 beforeEach 运行其回调之后。
回答by Andreas
yes, this scenario works fine for us. We use chutzpah to run the the tests in our gated checkins and our tests would fail without the afterEach
functions.
是的,这个场景对我们来说很好用。我们使用 chutzpah 在门控签入中运行测试,如果没有这些afterEach
功能,我们的测试将失败。
But the define
line looks like require.js
. We had several problems with that ...
I suppose that MyModule
is undefined
or not defined as expected. Have you tried to set a breakpoint in the beforeEach
method to see if it was called and what value MyModule
has? How are you calling the tests?
但这define
条线看起来像require.js
. 我们遇到了几个问题......我想这MyModule
是否undefined
按预期定义。您是否尝试在beforeEach
方法中设置断点以查看它是否被调用以及MyModule
具有什么值?你如何称呼测试?
When I run your code without the define
line the beforeEach
function gets called 4x - as expected. Btw I used chutzpah.console.exe to call the tests.
当我在没有该define
行的情况下运行您的代码时,该beforeEach
函数被调用了 4 次 - 正如预期的那样。顺便说一句,我使用 chutzpah.console.exe 来调用测试。
Edit:
编辑:
Yeah, now I can reproduce the problem on my PC. And it's much more clear to me.
At the beginning module
is undefined as every variable is undefined first. Then you register your functions in jasmine using beforeEach
and describe
. Jasmine starts with evaluating
是的,现在我可以在我的 PC 上重现该问题。对我来说更清楚。开头module
是未定义的,因为每个变量都是先未定义的。然后您使用beforeEach
和在 jasmine 中注册您的函数describe
。茉莉花从评估开始
function() {
commonTests({
module: module,
method: 'function1'
});
}
which was passed to the first describe
. At the line module: module
JS copies the referenceof var module
to the new objects property module
and this references undefined
so far. When the beforeEach
callback gets called it changes the reference of the var module
to the correct value but the wrong reference has already been copied ...
传递给第一个describe
. 在生产线module: module
JS复制引用的var module
新对象属性module
和该引用undefined
至今。当beforeEach
回调被调用时,它会将 的引用更改为var module
正确的值,但错误的引用已被复制......
I tried to move var module
above function commonTests
and used that variable in the tests instead of params.module
and they pass as expected. I don't know if that is an option in your environment but I hope it it helps.
我试图移动到var module
上面function commonTests
并在测试中使用该变量而不是params.module
它们按预期通过。我不知道这是否适用于您的环境,但我希望它有所帮助。
Greets, Andreas
你好,安德烈亚斯