首页 > 解决方案 > 如何用 sinon 监视由 EventEmitter 事件触发的回调调用?Javascript,ES6,单元测试,Chai

问题描述

我需要测试我的回调是否被调用了 n 次并且总是返回 true。
这是我在打字稿中的测试回调函数:

const checkBlockTransaction = (block: ILogsBlock) => {
  const tx = transactions.find(element => element.block === block.blockNumber);
  try {
    assert.strictEqual(block.transactions[0].amount, tx.amount);
  } catch (e) {
    return false;
  }
  return true;
};

这是我目前失败的测试,因为间谍没有注册任何函数调用

describe('Erc20DepositsWatcher', () => {
  it('handles blocks correctly', async () => {
    const spy = sinon.spy(checkBlockTransaction);
    for (const tx of transactions) {
      await deployedContract.methods.transfer(tx.address, tx.amount)
      .send({ from: addresses[0] });
    }

    depositsWatcher.subscribe(checkBlockTransaction);
    await depositsWatcher.startBroadcasting();
    await depositsWatcher.handleNewBlock(await web3.eth.getBlock('latest'));
    assert.equal(spy.callCount, 7);
    //sinon.assert.callCount(spy, 7);
    //assert(spy.alwaysReturned(true));
  });
});  

也许有比用 sinon 监视更好的解决方案,但我还没有找到

标签: javascriptecmascript-6sinonchaispy

解决方案


我目前的解决方案是没有间谍,但它不是很好看:

function checkCallbackCalled(done: any, callsNumber: number) {
  let counter = 0;
  return (block: ILogsBlock) => {
    const tx = transactions.find(element => element.block === block.blockNumber);
    try {
      assert.strictEqual(block.transactions[0].amount, tx.amount);
    } catch (e) {
      done(e);
    }
    counter += 1;
    if (counter === callsNumber) done();
  };
}

describe('Erc20DepositsWatcher', () => {
  it('handles blocks correctly', async (done) => {
    for (const tx of transactions) {
      await deployedContract.methods.transfer(tx.address, tx.amount)
      .send({ from: addresses[0] });
    }

    depositsWatcher.subscribe(checkCallbackCalled(done, 7));
    await depositsWatcher.startBroadcasting();
    await depositsWatcher.handleNewBlock(await web3.eth.getBlock('latest'));
  });
});

推荐阅读