首页 > 解决方案 > Jasmine 测试:如何测试 Promise.then() 块?

问题描述

我想测试一个场景,我正在调用一个函数(它返回一个 Promise),然后在 then 块中,我正在调用另一个名为 'callInThenBlock()' 的函数。我想测试当 then 块执行时,名为 count 的组件变量的值设置为 2,并调用了 calledInThenBlock()。

testIt(){
    this.returnPromise().then((res)=>{
      if(res.data[0].name=="Ankit"){
        this.count=2;
        this.calledInThenBlock();
      }
    }).catch(()=>{
      this.calledInCatchBlock();
    })
  }


 returnPromise(){
    return Promise.resolve({data:[{name:"Ankit"}]});
  }

我无法弄清楚如何测试这种情况。任何建议,将不胜感激。

谢谢!

标签: javascriptangularunit-testingjasminekarma-jasmine

解决方案


在您的代码中,您无需等待 Promise 解决。

testIt() {
  // testIt() returns before the Promise returned by returnPromise() is
  // resolved.
  this.returnPromise().then((res) => {
    if (res.data[0].name == "Ankit") {
      this.count = 2;
      this.calledInThenBlock();
    }
  }).catch(() => {
    this.calledInCatchBlock();
  })
}

it('test testIt()', () => {
  testIt();

  // okay, now how do I know when the Promise returned by returnPromise()
  // is resolved? Or when the value of count will change?
  // Of course, I can make it work by calling the assertions after an
  // arbitrary amount of time, but it doesn't seem like the natural way
  // of doing things.
});

代码很臭。依赖的客户testIt()希望知道它执行的工作何时完成。编写单元测试时也会变得很麻烦。testIt()调用后在测试用例中做出的任何断言都可能在 Promise 解决之前得到评估。将您的功能更改为以下将修复它。

testIt() async {
  try {
    const res = await this.returnPromise(); // wait for the Promise to resolve
    if (res.data[0].name == "Ankit") {
      this.count = 2;
      this.calledInThenBlock();
    }
  } catch (e) {
    this.calledInCatchBlock();
  }
}

要编写异步测试,您可以使用async/awaitJasmine来解决测试期间返回的承诺。

it('test Example#testIt()', async () => {
  const example = new Example(); // or however you instantiate it.
  await example.testIt(); // wait for the Promise to resolve

  // followed by assertions to validate behaviour correctness.
  expect(example.count).toEqual(2);
});

我提供的代码仅用于说明目的。它可能无法按原样工作。


推荐阅读