如何在模拟函数的回调中调用解析? [英] How do I call a resolve in the callback of a mocked function?

查看:74
本文介绍了如何在模拟函数的回调中调用解析?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我要测试的功能:

index.js:

import ThirdParty from 'third-party';

function Main(){}

Main.prototype.getStuff = function(){
   return new Promise((resolve, reject) => {
      this.getOtherStuff().then((data) => {
         // Business logic...
         const tpinstance = new ThirdParty();

         tpinstance.createThing().nestedFunction(null, () => {
             // This is where I'm resolving the outer function
             resolve({newdata: goodstuff});
         });
      });
   }
}

Main.prototype.getOtherStuff = function(){
   return new Promise((resolve, reject) => {
     resolve();
   })
}

我无法解决最外部功能的承诺,因此出现此错误:

I am failing to resolve the the promise from the outer most function so I'm getting this error:

超时-在jest.setTimeout.Error指定的5000ms超时内未调用异步回调:

Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.Error:

我的测试

//index.spec.js
import ThirdParty from 'third-party';

jest.mock('third-party');

describe('Main', () => {
   describe('#getStuff', () => {
      test('Want this to pass', async () => {

         jest
           .spyOn(Main.prototype, "getOtherStuff")
           .mockImplementationOnce(() => Promise.resolve({ data: "value" }));

         const mockedThing = {
            // This implementation seems wrong to me.
            nestedFunction: jest.fn().mockImplementation(() => Promise.resolve())
         }

         jest
           .spyOn(ThirdParty.prototype, "createThing")
           .mockImplementation(() => (mockedThing))

         let instance = new Main();
         await instance.getStuff();

         //assertions -> I never get here cause it timesout
         expect(Main.prototype.getOtherStuff).toHaveBeenCalled();
      });
   });
});

如何在将传递给nestedFunction的回调中解析外部函数的方式模拟出nestedFunction?

How can I mock out nestedFunction in a way where I'll be resolving the outer function in a callback I pass to nestedFunction?

推荐答案

这是单元测试解决方案:

Here is the unit test solution:

index.js:

import ThirdParty from "./third-party";

export default function Main() {}

Main.prototype.getStuff = function() {
  return new Promise((resolve, reject) => {
    this.getOtherStuff().then(data => {
      const tpinstance = new ThirdParty();
      tpinstance.createThing().nestedFunction(null, () => {
        const goodstuff = data;
        resolve({ newdata: goodstuff });
      });
    });
  });
};

Main.prototype.getOtherStuff = function() {
  return new Promise((resolve, reject) => {
    resolve();
  });
};

third-party.js:

export default function ThirdParty() {}

ThirdParty.prototype.createThing = function() {
  console.log("real create thing");
  return this;
};

ThirdParty.prototype.nestedFunction = function(arg, cb) {
  console.log("real nested function");
};

index.spec.js:

import Main from "./";
import ThirdParty from "./third-party";

jest.mock("./third-party.js", () => {
  const mThirdParth = {
    createThing: jest.fn().mockReturnThis(),
    nestedFunction: jest.fn()
  };
  return jest.fn(() => mThirdParth);
});

describe("Main", () => {
  describe("#getStuff", () => {
    afterEach(() => {
      jest.restoreAllMocks();
      jest.resetAllMocks();
    });
    it("should pass", async () => {
      jest
        .spyOn(Main.prototype, "getOtherStuff")
        .mockResolvedValueOnce({ data: "value" });

      let callback;
      const tpinstance = new ThirdParty();
      tpinstance.createThing().nestedFunction.mockImplementation((arg, cb) => {
        callback = cb;
        cb();
      });
      const instance = new Main();
      const pending = instance.getStuff();
      console.log(pending);
      const actual = await pending;
      expect(actual).toEqual({ newdata: { data: "value" } });
      expect(Main.prototype.getOtherStuff).toBeCalledTimes(1);
      expect(tpinstance.createThing).toHaveBeenCalled();
      expect(tpinstance.createThing().nestedFunction).toBeCalledWith(
        null,
        callback
      );
    });
  });
});

带有覆盖率报告的单元测试结果:

Unit test result with coverage report:

 PASS  src/stackoverflow/59150545/index.spec.js
  Main
    #getStuff
      ✓ should pass (12ms)

  console.log src/stackoverflow/59150545/index.spec.js:31
    Promise { <pending> }

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |    84.62 |      100 |    71.43 |    83.33 |                   |
 index.js |    84.62 |      100 |    71.43 |    83.33 |             18,19 |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        3.529s

源代码: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59150545

这篇关于如何在模拟函数的回调中调用解析?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆