【问题标题】:Jest test the resolve reject callback开玩笑测试解决拒绝回调
【发布时间】:2019-09-15 09:32:18
【问题描述】:

我有这个函数,它为 api 调用调用一个 util 函数。 util函数根据api结果解析或拒绝。

现在,我需要对具有以下结构的回调函数进行单元测试。

`theClassMethod : () => {
    return utilMethod().then(
    result => { this.functionOne() //Test this function is called }, 
    error => { this.functionTwo() //Test this function is called }
    )
}`

util 方法返回如下承诺:

utilFunc = (data :string) :Promise<ResultData[]> => {
    return new Promise(async (resolve, reject) => {
        try{
            resolve(data)
        }catch{
            reject(error)
        }
    }) 
}

https://codesandbox.io/s/vjnwy1zw75?fontsize=14

我尝试了什么:

  1. 模拟 util 方法来解决/拒绝。调用类方法并进行断言。它不起作用,并且测试总是作为误报通过。

我花了很多时间寻找类似的问题。这里的大多数问题都是测试代码,例如:

theClassMethod : () =&gt; { utilMethod.then().catch()}

我要解决的问题是在 then 块 then(function1, function2) 中测试解析,拒绝回调。必须测试 function1 中的代码块是否调用了一些预期的函数。

【问题讨论】:

  • 你的测试代码是否遵循jest guideline 来测试异步代码?
  • 是的,确实如此。勾选
  • 你能写出你的测试是什么样子的最小例子吗?
  • 请不要试图阻止重复的问题建议 - 读者无论如何都会提出它们。他们几乎总是乐于助人,对他们敞开心扉是理想的,即使你相信你已经彻底搜索过了。您可能没有看到好的复制品,或者您可能看过但不明白为什么它是复制品。

标签: javascript reactjs unit-testing promise jestjs


【解决方案1】:

您所描述的方法(模拟utilMethod 来解决/拒绝)是一个好方法。

这是一个简单的工作示例,可帮助您入门:

注意:我将functionOne 实现为类方法,将functionTwo 实现为实例属性,以展示如何监视两者函数类型:

util.js

export const utilMethod = async () => 'original';

code.js

import { utilMethod } from './util';

export class MyClass {
  functionOne() { }  // <= class method
  functionTwo = () => { }  // <= instance property
  theClassMethod() {
    return utilMethod().then(
      result => { this.functionOne() },
      error => { this.functionTwo() }
    );
  }
}

code.test.js

import { MyClass } from './code';
import * as util from './util';

test('theClassMethod', async () => {
  const mock = jest.spyOn(util, 'utilMethod');

  const instance = new MyClass();

  const functionOneSpy = jest.spyOn(MyClass.prototype, 'functionOne');  // <= class method
  const functionTwoSpy = jest.spyOn(instance, 'functionTwo');  // <= instance property

  mock.mockResolvedValue('mocked value');  // <= mock it to resolve
  await instance.theClassMethod();
  expect(functionOneSpy).toHaveBeenCalled();  // Success!

  mock.mockRejectedValue(new Error('something bad happened'));  // <= mock it to reject
  await instance.theClassMethod();
  expect(functionTwoSpy).toHaveBeenCalled();  // Success!
});

【讨论】:

  • 非常感谢您花时间解决这个问题。当成功回调只返回值时,此解决方案是正确的,但我的代码的结构方式是成功回调在其中调用了一个函数。我正在尝试测试是否成功调用该函数。问题不清楚是我的错,我现在已经更新了这个问题。有没有办法知道成功回调函数块中的函数是否被调用?
  • 我更新了我的答案以断言调用了函数。 @ebiv
  • 我还查看了您沙箱上的代码...看起来您只需将您的测试函数设为async 并在Promise 返回的instance.callThirdPartyAPI() 上调用await在断言您的间谍被调用之前确保它完成。 @ebiv
猜你喜欢
  • 2021-01-10
  • 1970-01-01
  • 2017-09-11
  • 2020-08-16
  • 2017-07-11
  • 1970-01-01
  • 2019-06-30
  • 2018-03-13
  • 2021-11-30
相关资源
最近更新 更多