[英]'it' block executes multiple times until 'done' is called in Jasmine 2.0
I am creating a test case in Jasmine 2.0 我正在Jasmine 2.0中创建一个测试用例
describe("TestCase", function(){
var originalTimeout=0;
beforeEach(function(){
originalTimeout=jasmine.DEFAULT_TIMEOUT_INTERVAL;
jasmine.DEFAULT_TIMEOUT_INTERVAL=10000;
});
afterEach(function(){
jasmine.DEFAULT_TIMEOUT_INTERVAL=originalTimeout;
});
it("check timeout", function(done){
var startTime=new Date().getTime() / 1000; //line 15
setTimeout(function(){
var currentTime=new Date().getTime() / 1000;
expect(currentTime).toBeGreaterThan(startTime);
done();
},5000);
});
});
While debugging it I noticed that if we keep a breakpoint at line 15, it gets hit again and again until done in the setTimeout is called. 在调试它时,我注意到,如果我们在第15行保留一个断点,它将断断续续地命中,直到在setTimeout中调用完为止。 Is there any explaination for this behavior?
有这种现象的解释吗? This behavior leads to execution of same test again and again.
此行为导致一次又一次执行相同的测试。
Ok, I've had a good look through the Jasmine source and I see that a lot of work has been done between 1.x -- 2.x -- master in this area. 好的,我对Jasmine源码有了很好的了解,我发现在1.x-2.x-大师之间已经完成了很多工作。
However, I cannot find a loop where the same it gets called again and again waiting for the done()
to be called. 但是,我找不到一个循环,在该循环中一次又一次地等待它被调用,并等待
done()
被调用。
Here is the relevant code from 2.0 : 这是2.0中的相关代码:
if (fn.length > 0) {
attempt(function() { fn.call(self, function() { self.run(fns, index + 1) }) });
} else {
attempt(function() { fn.call(self); });
self.run(fns, index + 1);
}
function attempt(fn) {
try {
fn();
} catch (e) {
self.onException(e);
if (!self.catchingExceptions()) {
//TODO: set a var when we catch an exception and
//use a finally block to close the loop in a nice way..
throw e;
}
}
}
You can see that the above code checks to see if there is a done
argument fn.length > 0
and then creates the done
as the call to execute the next test case. 您可以看到上面的代码检查是否有
done
参数fn.length > 0
,然后创建done
作为调用以执行下一个测试用例。
This is similar to the code on master (however, master has changed a lot): 这类似于master上的代码(但是master改变了很多):
for(iterativeIndex = recursiveIndex; iterativeIndex < length; iterativeIndex++) {
var queueableFn = queueableFns[iterativeIndex];
if (queueableFn.fn.length > 0) {
attemptAsync(queueableFn);
return;
} else {
attemptSync(queueableFn);
}
}
function attemptAsync(queueableFn) {
var clearTimeout = function () {
Function.prototype.apply.apply(self.timeout.clearTimeout, [j$.getGlobal(), [timeoutId]]);
},
next = once(function () {
clearTimeout(timeoutId);
self.run(queueableFns, iterativeIndex + 1);
}),
timeoutId;
next.fail = function() {
self.fail.apply(null, arguments);
next();
};
if (queueableFn.timeout) {
timeoutId = Function.prototype.apply.apply(self.timeout.setTimeout, [j$.getGlobal(), [function() {
var error = new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.');
onException(error, queueableFn);
next();
}, queueableFn.timeout()]]);
}
try {
queueableFn.fn.call(self.userContext, next);
} catch (e) {
handleException(e, queueableFn);
next();
}
}
This is largely similar except for a couple changes. 除了几处更改外,这在很大程度上相似。 First, code adds another
setTimeout
around the async call (and adds a timeout error message). 首先,代码在异步调用周围添加了另一个
setTimeout
(并添加了超时错误消息)。 Second, the call to the next test case is also wrapped in a call to once
: 其次,对下一个测试用例的调用也包含在对
once
的调用中:
function once(fn) {
var called = false;
return function() {
if (!called) {
called = true;
fn();
}
};
}
The once
function makes sure that the test is only called once. once
函数可确保测试仅被调用一次。 Which makes me thing that there was a bug in 2.0 (that I don't see) whereby the test was being called again and again. 这让我觉得2.0中有一个错误(我没有看到),该错误一次又一次地调用了测试。
Although inconclusive, this might give you some ideas. 尽管没有定论,但这可能会给您一些想法。 It may be an IDE issue instead of a Jasmine issue.
这可能是IDE问题,而不是Jasmine问题。
Anyway, I hope this helps. 无论如何,我希望这会有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.