当在内部函数中调用 "done()" 时,将 mocha "done()" 测试转换为 "async"

Converting a mocha "done()" test to "async" when "done()" is called in an inner function

我想在下面的测试中添加对同步函数的调用:

describe('the server', function() {
  it('should respond to a udp packet', function(done) {

    // TODO: call async function here

    const udp = dgram.createSocket('udp4');

    udp.on('error', function(error) {
      console.log(error);
    });

    udp.on('message', function(msg, rinfo) {
      console.log('msg', msg);
      console.log('rinfo', rinfo);
      // TODO: check the reply
      udp.close();
      done();
    });
    udp.bind();

    // send a request
    const bytes = Buffer.from("421a0800117860bc457f0100001a0653455256455222054d54303031", 'hex');
    udp.send(bytes, SERVER_PORT, SERVER_ADDR)
  });
});

如果我只添加 async,使:

it('should respond to a udp packet', async function(done) { 

我得到一个错误:

1) the server
     should respond to a udp packet:
   Error: Resolution method is overspecified. Specify a callback *or* return a Promise; not both.

但我需要 done 因为测试只有在从服务器收到数据包时才结束。

有没有办法只从内部函数中的异步函数“返回”?

这里至少有两种方法:使用由异步调用 returned 的承诺或使整个测试函数异步。我将展示第二种方法,因为在不知道待办事项中的异步函数调用是什么样子的情况下更容易实现。

基本上要完成三个更改:

  • 使测试函数异步并删除 done 参数。
  • 在承诺中包装使用 done 回调的语句或语句组。如果您想保留该名称,请将承诺回调的第一个参数命名为 done
  • return 承诺。
describe('the server', function() {
  it('should respond to a udp packet', async function() {

    // TODO: call async function here

    const udp = dgram.createSocket('udp4');

    udp.on('error', function(error) {
      console.log(error);
    });

    const promise = new Promise(done => {
      udp.on('message', function(msg, rinfo) {
        console.log('msg', msg);
        console.log('rinfo', rinfo);
        // TODO: check the reply
        udp.close();
        done();
      });
    });

    udp.bind();

    // send a request
    const bytes = Buffer.from("421a0800117860bc457f0100001a0653455256455222054d54303031", 'hex');
    udp.send(bytes, SERVER_PORT, SERVER_ADDR);
    return promise;
  });
});

这应该足以进行测试。为了更准确的错误处理,您可能希望在出现异常时拒绝承诺:

const promise = new Promise((done, reject) => {
    try {
      udp.on('message', function(msg, rinfo) {
      console.log('msg', msg);
      console.log('rinfo', rinfo);
      // TODO: check the reply
      udp.close();
    } catch (err) {
      reject(err);
      return;
    }
    done();
  });
});

你也可以使用mocha --exit,这比你自己清理要简单得多。