简体   繁体   English

开玩笑单元测试 function 调用第二个返回 promise

[英]Jest Unit Testing function that calls a second one that returns a promise

Edited Question with vazsonyidl suggestions applied应用了 vazsonyidl 建议的已编辑问题

I have to write unit tests for a function similar to this one:我必须为类似于此的 function 编写单元测试:

import {External} from 'ExternalModule';

async functionA(){
    this.functionB().then((data) => {
        External.functionC(options);
        console.log("Reached1");

    }).catch((data) => {
        const { OnError = "" } = data || {}
        if(OnError) {
            External.functionC(anotherOptions);
            console.log("Reached2");
        }
    })
}

functionB() {
    return new Promise(() => {
    });
  }

As functionC belongs to another module, I placed a mock of it in the _mocks_ folder:由于 functionC 属于另一个模块,我将它的模拟放在_mocks_文件夹中:

//_mocks_/ExternalModule.ts

export var External: ExternalClass = {
  functionC(){}
}

class ExternalClass{
  constructor(){};
  functionC(){};
}

I have mocked functionB in two diferent ways for testing the then and the catch :我以两种不同的方式模拟了 functionB 来测试thencatch

it("should test then block", () => {
        functionB = jest.fn(() => {return Promise.resolve()});

        const functionSpy = jest.spyOn(ExternalModule.External, 'functionC');
        void functionA().then(() => {
          expect(functionSpy).not.toHaveBeenCalled();
        });
    })

it("should test catch block", () => {
        const err = { OnError: "Error" };
        functionB = jest.fn(() => {return Promise.reject(err)});

        const functionSpy = jest.spyOn(ExternalModule.External, 'functionC');
        void functionA().then(() => {
          expect(functionSpy).not.toHaveBeenCalled();
        });
    })

What I am trying to do is expect that functionC was called and called with the correct params, but the test is always passing even if I test if functionC was not called.我想要做的是期望 functionC 被调用并使用正确的参数调用,但是即使我测试 functionC 是否没有被调用,测试也总是通过。

What am I doing wrong?我究竟做错了什么?

I think when this function catch error, this error should have an 'OnError' property so the functionC can run.我认为当这个 function 捕获错误时,这个错误应该有一个 'OnError' 属性,以便函数 C 可以运行。

const { OnError = "" } = data || {}
if(OnError) {
    ExternalClass.functionC(anotherOptions);
}

change you response error data to return Promise.reject({OnError: '404'}) may solve this problem.更改您的响应错误数据以return Promise.reject({OnError: '404'})可能会解决此问题。

Because you are not providing it to your class.因为您没有将它提供给您的 class。 The following code is working for me:以下代码对我有用:

 class A { async functionA() { this.functionB().then((data) => { this.functionC(); // It woll log aaa here, you need this one. }).catch((data) => { const {OnError = ''} = data || {}; if (OnError) { console.log('onerror'); } }); } functionB() { return new Promise(() => { }); } functionC() { return 2; } } describe('a', () => { it('test', () => { const a = new A(); a.functionB = jest.fn(() => Promise.resolve()); const functionBSpy = jest.spyOn(a, 'functionC'); void a.functionA().then(() => { expect(functionBSpy).toHaveBeenCalledTimes(1); }); }); });

Hope this helps, any comment appreciated.希望这会有所帮助,任何评论表示赞赏。

As you provided no information about your functionB I mocked something that may suitable for you .由于您没有提供有关您的功能 B 的信息,我嘲笑了一些可能适合您的东西

Your original problem is that Jest does not wait for your callbacks to settle.您最初的问题是 Jest 不会等待您的回调解决。 It does the assertion although, even if your function calls happen later, Jest will not recognise them and says that no call ever occurred.尽管它会进行断言,但即使您的 function 调用稍后发生,Jest 也不会识别它们并说从未发生过调用。

There are several docs available, for example Jest's one here有几个可用的文档,例如 Jest's one here

Jest does not wait for the async code to complete before doing assertions. Jest 在进行断言之前不会等待异步代码完成。

You can use the following function:您可以使用以下 function:

const waitForPromises = () => new Promise(setImmediate);

to force Jest to wait for promises to complete before continuing like so:强制 Jest 在继续之前等待承诺完成:


it("does something", async () => {
  promiseCall();
  await waitForPromises();
  expect(something).toBe(something)
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM