我有以下测试案例:
it("should pass the test", async function (done) {
await asyncFunction();
true.should.eq(true);
done();
});
运行它断言:
错误:分辨率方法被过度指定。指定回调或 返回诺言;不是两者。
,如果我删除了 done();
语句,则断言:
错误:超过2000ms的超时。对于异步测试和钩子,请确保 " DONE()"称为;如果返回诺言,请确保其解决。
如何解决这个悖论?
您还需要删除done
参数,而不仅仅是调用它。诸如Mocha之类的测试框架查看该功能的参数列表(或至少其ARITY),以了解您是使用done
还是类似的。
使用Mocha 3.5.3,这对我有用(必须将true.should.be(true)
更改为assert.ok(true)
,因为前者丢了一个错误):
const assert = require('assert');
function asyncFunction() {
return new Promise(resolve => {
setTimeout(resolve, 10);
});
}
describe('Container', function() {
describe('Foo', function() {
it("should pass the test", async function () {
await asyncFunction();
assert.ok(true);
});
});
});
但是,如果我添加 done
:
describe('Container', function() {
describe('Foo', function() {
it("should pass the test", async function (done) { // <==== Here
await asyncFunction();
assert.ok(true);
});
});
});
...然后我得到
错误:超过2000ms的超时。对于异步测试和钩子,请确保"完成()"为" DONE DONE";如果返回诺言,请确保其解决。
删除作为参数的删除对我有用!相反,只使用期望/应该。示例如下:
getResponse(unitData, function callBack(unit, error, data){ try {
return request.post(unit, function (err, resp) {
if (!err && resp.statusCode === 200) {
if (resp.body.error) {
return callback(obj, JSON.stringify(resp.body.error), null);
}
return callback(obj, null, resp);
} else {
if (err == null) {
err = { statusCode: resp.statusCode, error: 'Error occured.' };
}
return callback(obj, err, null);
}
});
} catch (err) {
return callback(obj, err, null);
}}
之前:
it('receives successful response', async (done) => {
const getSomeData = await getResponse(unitData, function callBack(unit, error, data){
expect(data.statusCode).to.be.equal(200);
done();
}) })
(工作)之后:
it('receives successful response', async () => {
const getSomeData = await getResponse(unitData, function callBack(unit, error, data){
expect(data.statusCode).to.be.equal(200);
}) })
有时需要在摩卡中使用 async/await
done
功能。
例如,在我的socket.io
单元测试用例之一中,我必须使用异步功能和测试套接字事件处理程序调用DB功能,这是回调功能:
context("on INIT_CHAT", ()=> {
it("should create a room", async (done) => {
const user = await factory.create("User");
socket.emit("INIT_CHAT", user);
socket.on("JOIN_CHAT", async (roomId) => {
const room = await ChatRoom.findByPk(roomId);
expect(room).to.exist;
// then I need to close a test case here
done();
});
});
});
这将导致与OP中完全相同的错误:
错误:分辨率方法被过度指定。指定回调或返回承诺;不是两者。
我的解决方法:
我只是将整个测试代码包裹在承诺生成器中:
context("on INIT_CHAT", ()=> {
it("should create a room", async () => {
const asyncWrapper = () => {
return new Promise(async (resolve) => {
const user = await factory.create("User");
socket.emit("INIT_CHAT", user);
socket.on("JOIN_CHAT", async (roomId) => {
const room = await ChatRoom.findByPk(roomId);
expect(room).to.exist;
resolve(true);
});
});
});
await asyncWrapper();
});
});