Mocha Done()和异步等待着矛盾的问题



我有以下测试案例:

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();
  });
});

最新更新