函数在promise被解析后被调用,但Jasmine未通过测试.为什么?

Function is called after promise is resolved but Jasmine fails the test. Why?

本文关键字:Jasmine 测试 为什么 promise 调用 函数      更新时间:2023-09-26

我的应用程序使用一个返回承诺的服务,该承诺通常依赖于一大堆其他承诺。我已经将其重构为单独的命名函数,以使测试(和可读性)更容易。所以在这种情况下,我只想测试run函数是否完成了它的工作并调用了其他函数。

例如

run() {
    return myService
    .connection
    .then(this.namedFunction1)
    .then(this.namedFunction2)
    .then(this.namedFunction3)
    .catch((error) => {
      console.log("doh!", error.stack);
    });

当我测试namedFunction1被称为Jasmine时失败了,尽管事实并非如此。下面是我为保持简单而编写的一个小代码示例:

getString() {
    return Promise.resolve("Heeeelp. Heeeelp!!");
  }
  printToConsole(string) {
    console.log(string); // This works! but Jasmine says nay :( 
  }
  myFunction() {
    this.getString()
    .then(this.printToConsole)
    .catch((error) => {
      console.log("Some error occurred", error);
    });
  }

以及测试:

it("should call the printToConsole function", function() {
      spyOn(myClass, "printToConsole").and.callThrough(); //added the call through so it would print
      myClass.myFunction();
      expect(myClass.printToConsole).toHaveBeenCalled();
    });

以及输出。。。

> Started F[2016-05-16 11:32:31.898] console - Heeeelp. Heeeelp!!
> 
> 
> Failures: 1) MyClass myFunction should call the printToConsole
> function   Message:
>     Expected spy printToConsole to have been called.   Stack:
>     Error: Expected spy printToConsole to have been called.

我尝试添加jasmine asynch done()函数,但没有成功,最终我在示例中立即解决了这个问题。

那么,为什么或者怎么会失败呢?

如有任何帮助,我们将不胜感激。谢谢

因为myFunction是一个异步操作。myFunction调用一个异步函数,然后立即返回,然后激发测试断言。此时,printToConsole实际上还没有被调用。您需要使用Jasmine的异步测试支持来成功运行此测试。

您需要修改myFunction以返回承诺,这样您就可以知道它何时完成:

myFunction() {
  return this.getString()
  .then(this.printToConsole)
  .catch((error) => {
    console.log("Some error occurred", error);
  });
}

然后您将修改您的测试以使用Jasmine提供的done功能:

it("should call the printToConsole function", function(done) {
  spyOn(myClass, "printToConsole").and.callThrough(); //added the call through so it would print
  myClass.myFunction().then(function () {
    expect(myClass.printToConsole).toHaveBeenCalled();
    done();
  }).catch(done); // to make sure the test reports any errors
});

这应该会让事情运转起来。