如何模拟readline.on('SIGINT')

How to mock readline.on('SIGINT')?

本文关键字:何模拟 SIGINT on readline 模拟      更新时间:2023-09-26

我有这段代码:

function getMsg() {
  return new Promise(function (resolve, reject) {
    var input = [];
    var rl = readline.createInterface({
      input: process.stdin,
      output: process.stdout
    });
    rl.on('line', function (cmd) {
      if (cmd.trim()) {
        input.push(cmd);
      } else {
        rl.close();
      }
    });
    rl.on('close', function () {
      rl.close();
      resolve(input.join(''n'));
    });
    rl.on('SIGINT', reject);
  });
}

我正在尝试测试这个函数,我的尝试,到目前为止,是:

it('should reject if SIGINT is sent', function () {
  sandbox.stub(readline, 'createInterface', function () {
    return {
      on: function (action, callback) {
        callback();
      },
      prompt: function () {},
      close: function () {}
    };
  });
  return getMsg().then(null).catch(function () {
    expect(true).to.be.equal(true);
  });
});

当然,这并不能模拟SIGINT,我该怎么做呢?

我认为你需要一个不同的设置:

const EventEmitter = require('events').EventEmitter
...
it('should reject if SIGINT is sent', function () {
  let emitter = new EventEmitter();
  sandbox.stub(readline, 'createInterface', function () {
    emitter.close = () => {};
    return emitter;
  });
  let promise = getMsg().then(function() {
    throw Error('should not have resolved');
  }, function (err) {
    expect(true).to.be.equal(true);
  });
  emitter.emit('SIGINT');
  return promise;
});

readline.createInterface()返回的对象继承自EventEmitter,所以这就是存根将返回的对象。附加的close函数只是添加到它中,以便在调用它时防止错误。

你不能直接返回getMsg返回的承诺,因为这不会给你一个机会发出SIGINT"信号"(实际上只是一个事件,但为了测试目的,它会工作得很好)。

测试应该在调用" completed "处理程序时失败,这必须显式地完成,否则Mocha认为测试通过了。

接下来,发送SIGINT(它应该按预期触发拒绝处理程序),并返回承诺。