问题
I am using a library (pouchDB) that does some async operations. To keep things simple, I will keep the details out of it as I think this is a general issue with "unit testing" involving async operations (unit testing in quotation marks because I guess this isn't truly unit testing if I am testing integration with another library. But, using QUnit seems like the most appropriate way to write tests for it).
I am using QUnit to do my js unit testing. I have two tests. I am finding that if I run either one (while having the other commented out) they will pass. If I run both of them together, the run that runs second will fail. It looks like the second one is running before the teardown for the first is complete which stops the setup for the second one from completing successfully.
module("pouchDB integration specs", {
setup: function(){
//some setup stuff
}
},
teardown: function(){
//some teardown stuff
});
}
});
asyncTest("test1", 1, function(){
test1MethodBeingTested();
document.addEventListener("completedTest1Stuff", function(){
deepEqual(newFriendSchedule, 'new', "Test 1 Looks Good'");
start();
});
});
});
asyncTest("test2", 2, function(){
stuffBeingTestedForTest2();
document.addEventListener("test 2 stuff done", function(){
deepEqual(expectedTest2Result, actualTest1Result, "test 2 looks good!");
start();
})
});
(Apologies for the crap indenting. SO's editor doesn't like me no matter how much I wrestle with it)
I had a look at Martin Fowler's take on testing asynchronous code but my takeaway from that was "you should design your code to not be inherently async." Which doesn't help, since I am testing integration with a library which I don't want to modify (nor do I think I should have to - surely this issue has been dealt with before?)
回答1:
Similar to test methods, you can use stop
and start
in your teardown code to pause the test runner until your clean-up code is done (asyncTest
does an implicit call to stop
). QUnit uses a counting semaphore for stop
/start
calls, so you can call stop
multiple times if you've got more than one asynchronous task.
Quick example:
var teardownDone = false;
var tests = 0;
var testContent = function() {
if (tests > 0) {
QUnit.ok(teardownDone);
} else {
QUnit.ok(true);
tests++;
}
};
module('example', {
teardown: function () {
// Without this call and the subsequent start(), tests will fail.
stop();
setTimeout(function () {
teardownDone = true;
start();
}, 1000);
}
});
test('test1', testContent);
test('test2', testContent);
JSFiddle
来源:https://stackoverflow.com/questions/23401474/how-can-i-write-tests-that-have-setup-and-teardown-operations-that-are-asynchron