我遇到了问题:
var async = require('async');
function a() {
async.series([b,c], function(err) {
console.log('Done');
});
};
function b(next) {
next();
};
function c(next) {
next();
};
var methods = {
a: a,
b: b,
c: c
};
我正在尝试编写一个类似的测试:
spyOn(methods.a);
methods.a();
expect(methods.b).toHaveBeenCalled();
expect(methods.c).toHaveBeenCalled();
然而,b和c都没有注册为已被调用。任何想法如何正确测试这种行为?
答案 0 :(得分:0)
如果你在函数或方法上使用间谍,那么Jasmine会看看这个函数来检查它。 Jasmine Spy下的被调用函数默认不执行其代码。
spyOn(methods, "a");
methods.a();
expect(methods.a).toHaveBeenCalled();
在您的情况下,您需要检查异步代码执行。我们可以使用done
函数:
it("should support async execution", function(done) {
var MAX_ASYNC_DELAY = 2000;
spyOn(methods, "b");
spyOn(methods, "с");
methods.a();
setTimeout(function(){
expect(methods.b).toHaveBeenCalled();
expect(methods.c).toHaveBeenCalled();
done();
}, MAX_ASYNC_DELAY );
});
如果在methods.a()
中您将使用下一个:
function a() {
async.series([methods.b, methods.c], function(err) {
console.log('Done');
});
}
如果无法进行此类调整,则应重写以下测试用例:
it("should support async execution", function(done) {
var MAX_ASYNC_DELAY = 2000;
spyOn(window, "b");
spyOn(window, "с");
methods.a();
setTimeout(function(){
expect(b).toHaveBeenCalled();
expect(c).toHaveBeenCalled();
done();
}, MAX_ASYNC_DELAY );
});
Owen Ayres建议不要在测试用例中使用setTimeout
。但是如果你使用的是Jasmine,这在你的情况下是不可能的。因为jasmine.DEFAULT_TIMEOUT_INTERVAL
超时等待调用done
函数。
例如,您的异步超时几乎是10000毫秒,并将MAX_ASYNC_DELAY
设置为11000毫秒。测试用例将被标记为失败,因为jasmine.DEFAULT_TIMEOUT_INTERVAL
默认等于5000毫秒。需要使用覆盖此参数:
var originalTimeout;
beforeEach(function() {
originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
jasmine.DEFAULT_TIMEOUT_INTERVAL = 12000; // ms to wait for done()
});
it("should support async execution", function(done) {
var MAX_ASYNC_DELAY = 11000;
// test case from above
});
afterEach(function() {
jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
});
如果你使用Jasmine 2.2及以上版本,你可以写:
it("should support async execution", function(done) {
var MAX_ASYNC_DELAY = 11000;
// test case from above
}, 12000);
答案 1 :(得分:0)
不惜一切代价避免单位测试setTimeout
。以下是如何在可读的“三A测试”中对其进行测试的方法。格式。如果从未进行函数调用,则使用Jasmine的异步done
将确保它在失败之前等待一段时间。如果你想为这个测试用例自定义这个,你可以做我在下面的beforeEach中定义的东西(但是在测试本身里面)。
beforeEach(function() {
// these are not required, including to show you can have if desired
originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; // ms to wait for done()
});
it('calls methods b and c when a is called', function (done) {
var a = spyOn(methods.a);
var b = spyOn(methods.b);
methods.a();
expect(a).toHaveBeenCalled();
expect(b).toHaveBeenCalled();
done();
});
afterEach(function() {
// could be inline of above test if not needed for multiple cases.
jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
});
不要在测试中使用超时。这不是一种干净的测试方式,应该避免,除非绝对必不可少。