【问题标题】:Asserting function calls inside a promise在 Promise 中断言函数调用
【发布时间】:2016-07-11 14:15:56
【问题描述】:

我正在为异步 node.js 函数编写一些测试,该函数使用 Mocha、Chai 和 Sinon 库返回一个 Promise。
假设这是我的功能:

function foo(params) {
  return (
    mkdir(params)
    .then(dir => writeFile(dir))
  )
}

mkdirwriteFile 都是返回承诺的异步函数。
我需要测试 mkdir 是否被调用一次,并将 params 提供给 foo

我该怎么做?
我已经看过很多关于如何断言 foo 的整体返回值的示例(sinon-as-promised 对此非常有帮助),但没有关于如何确保在 promise 中调用各个函数。

也许我忽略了某些东西,这不是正确的方法吗?

【问题讨论】:

  • mkdir 不是在 Promise 中调用的,而是从 foo 同步调用的,你可以像往常一样测试它吗?还是要测试是否调用了writeFile

标签: javascript node.js promise mocha.js sinon


【解决方案1】:

mkdir 这里没有异步调用,所以测试起来比较简单:

mkdir = sinon.stub().resolves("test/dir")
foo(testparams)
assert(mkdir.calledOnce)
assert(mkdir.calledWith(testparams))
…

如果你想测试 writeFile 是否被调用,那只是稍微复杂一点——我们必须等待 foo 返回的承诺,然后再断言:

… // mdir like above
writeFile = sinon.stub().resolves("result")
return foo(testparams).then(r => {
    assert.strictEqual(r, "result")
    assert(writeFile.calledOnce)
    assert(writeFile.calledWith("test/dir"))
    …
})

【讨论】:

    【解决方案2】:

    您可以模拟mkdir 函数,然后使用setTimeout 来检查该函数是否被调用。

    describe('foo', () => {
      it('should call mkdir', () => {
        return new Promise((resolve, reject) => {
          let originalFunction = mkdir;
          let timer = setTimeout(() => {
            reject(`mkdir has not been called`);
          });
          mkdir = (...params) => new Promise(mkdirResolve => {
            //restore the original method as soon as it is invoked
            mkdir = originalMethod;
            clearTimeout(timer);
            mkdirResolve(someExpectedData);
            resolve();
          });
          foo(params);
        });
      });
    });
    

    【讨论】:

    • 更好:不要使用超时,而只是挂钩foo 返回的承诺。
    • @Bergi 我认为这将是一个有趣的答案。
    猜你喜欢
    • 2017-03-19
    • 1970-01-01
    • 1970-01-01
    • 2023-01-20
    • 2014-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-20
    相关资源
    最近更新 更多