【问题标题】:Should a function calling promise and not returning anything be considered an error?一个调用promise但不返回任何东西的函数是否应该被视为错误?
【发布时间】:2018-09-18 00:20:29
【问题描述】:

我有一个看起来像这样的方法:

doSomething(){
     return somethingPromisy().then((blerp) => {
         // do something with blerp
         return blerp;  // Modified, of course
     });
};

然后我有另一个方法看起来像这样:

doSomethingElse(){
    stepOne();
    var x = stepTwo();
    var y = stepThree(x);
    doSomething.then((data) => {
        stepFour(data + y);
    });
};

我正在使用 mocha+chai+sinon 来测试这段代码,特别是doSomethingElse,然后我想做出一些断言 - 但是我如何保证在我做出断言时承诺会得到解决?我知道一种选择是将其更改为:

doSomethingElse(){
    /* ... */
    return doSomething.then(...);
};

如果我这样做,那么编写我的测试就很容易了,因为它是:

return doSomethingElse().then(() => {
    someFake.lastCall.args.should.deep.equal(expectedData);
});

在我的测试中,一切都很好。但是我应该仅仅为了回报承诺而回报承诺吗?我实际上并不关心来自 doSomethingElse 的任何类型的返回值 - 我只关心当我测试 doSomething.then 中的函数被调用时,即 doSomething 承诺有在我做我的断言时已经解决了。

那么解决这个问题的“最佳”方法是什么?

【问题讨论】:

  • 是的,关于每个异步执行的函数都应该返回一个承诺。而不是(仅仅)因为 promise 中的结果值,而恰恰是因为你可以等待它。
  • 如果你的 doSomethingElse 函数是如此高级以至于它被不需要等待它的东西调用,因此没有将承诺传递给它的调用者,它应该有一个.catch() 链末尾的处理程序。

标签: javascript testing promise


【解决方案1】:

您应该使用 doSomething 的模拟与 doSomethingElse 分别测试 doSomething 和 doSomethingElse,并使用模拟的 then 方法返回您的测试值。你基本上想分别测试它们而不是同时。在这种情况下,您基本上将 doSomething 和 doSomethingElse 耦合在一起,这使得测试更加困难。测试应该很简单,你不是在测试 Promise 是否有效,所以使用一个假的来继续测试逻辑!

我自己并不认为缺少返回值是一个问题,有一个返回值,你只是链接它,而不是存储它。

【讨论】:

  • 在这种特殊情况下,我不一定要调用doSomething - 该函数的存在与此 API 100% 无关。我可以用其中的代码替换函数调用,我的测试不必更改。这就是为什么我不想模拟这个函数,因为函数的存在不是我想在我的测试中编码的东西,只是它的行为。
  • @WayneWerner 你是对的,你可以将代码直接放在行中,应该能够得到相同的结果。这就是重点。您应该单独测试 stepOne()、stepTwo()、stepThree(x)、stepFour(data + y);一旦你对这些进行了测试(或者如果你已经做得很好了!)你基本上只是在测试序列,但这为什么重要呢?如果函数为正确的输入返回正确的值,并且测试可以表明您不必担心像这样的测试顺序。特别是因为您的示例没有返回任何内容,这意味着您很好地测试了这些部分
猜你喜欢
  • 1970-01-01
  • 2016-11-10
  • 2019-12-23
  • 2019-08-09
  • 2023-02-07
  • 2019-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多