我有以下测试用例:
it("should pass the test", async function (done) {
await asyncFunction();
true.should.eq(true);
done();
});
运行它断言:
错误:分辨率方法过分指定。指定回调或 回报承诺;不是两个。
如果我删除done();
语句,它会断言:
错误:超出2000毫秒超时。对于异步测试和挂钩,请确保 "()完成"叫做;如果返回Promise,请确保它已解决。
如何解决这个悖论?
答案 0 :(得分:10)
您还需要删除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);
});
});
});
...然后我得到了
错误:超出2000毫秒超时。对于异步测试和挂钩,请确保&#34; done()&#34;叫做;如果返回Promise,请确保它已解决。
答案 1 :(得分:0)
从中删除作为参数的工作对我有用!只能使用Expect / should。示例如下:
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);
}) })
答案 2 :(得分:0)
有时需要在 mocha 中使用 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 中完全相同的错误:
<块引用>错误:解析方法被过度指定。指定回调或返回 Promise;不能两者兼而有之。
我只是将整个测试代码包装在一个 Promise 生成器中:
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();
});
});