简体   繁体   English

如何使用 Jest 测试动态导入(然后和捕获)

[英]How to test dynamic imports (then and catch) with Jest

So I have been struggling with how to test dynamic imports generally and in this case, especially in jest, I have been reading a lot on the internet but did not find anything concrete, so I thought about bringing the question up to centralize a decent solution.所以我一直在努力如何测试动态导入,在这种情况下,尤其是在开玩笑,我在互联网上阅读了很多,但没有找到任何具体的东西,所以我考虑提出这个问题以集中一个体面的解决方案.

I have the following methods inside of a class我在一个类中有以下方法

class MyClass {
   successMethod() {  ...  }

   errorMethod() { ... }

    myMethod() {
        return import('./myFile.js')
           .then(() => this.successMethod())
           .catch(() => this.errorMethod());
    }
}

My question is:我的问题是:

How do you mock both Success and Failing promise cases for this dynamic import using Jest to make sure each method ( successMethod and errorMethod ) are called when resolving or failing respectively?.您如何使用 Jest 模拟此动态导入的 Success 和 Failing 承诺案例,以确保分别在解决或失败时调用每个方法( successMethoderrorMethod )?

I found jest.doMock helps for mocking the resolved case but did not find a way to make the dynamic import fail by mocking it so the catch case is uncovered.我发现jest.doMock有助于jest.doMock已解决的案例,但没有找到通过模拟它来使动态导入失败的方法,以便发现catch案例。

Note: this is not a react application, this is a Vanilla JS project.注意:这不是一个 React 应用程序,这是一个 Vanilla JS 项目。

Prototype methods can be spied or mocked on either MyClass.prototype or class instance.可以在MyClass.prototype或类实例上监视或模拟原型方法。 Module mocks and spy functions should be restored for each test in order for them to not affect each other.应该为每个测试恢复模块模拟和间谍功能,以便它们不会相互影响。

let myClass;
beforeEach(() => {
  jest.resetModules();
  jest.restoreAllMocks();
  myClass = new MyClass();
  jest.spyOn(myClass, 'successMethod');
  jest.spyOn(myClass, 'errorMethod');
});

jest.doMock requires to import all affected modules after it was called. jest.doMock需要在调用后导入所有受影响的模块。 In order for dynamic import to result in rejected promise, myFile module should throw an error when evaluated.为了动态import导致被拒绝的承诺, myFile模块在评估时应该抛出一个错误。 Since dynamic import returns a promise, tests should be asynchronous.由于动态import返回一个承诺,测试应该是异步的。

it('...', async () => {
  jest.mock('./myFile.js', () => 'value');
  await expect(myClass.myMethod()).resolves.toEqual(/* return value from successMethod */);
  expect(myClass.successMethod).toBeCalled();
  expect(myClass.errorMethod).not.toBeCalled();
});

it('...', async () => {
  jest.mock('./myFile.js', () => { throw new Error() });
  await expect(myClass.myMethod()).rejects.toThrow(/* error message from errorMethod */);
  expect(myClass.successMethod).not.toBeCalled();
  expect(myClass.errorMethod).toBeCalled();
});

maybe something like也许像

beforeEach(() => {
  jest.resetModules();
});
beforeAll(() => {
  MyClass.mockImplementation(() => {
    return {
      successMethod: () => {
        console.log("succees");
      },
      errorMethod: () => {
        console.log("error");
      }
    };
  });
});

test("should fail", () => {
  jest.doMock("./myFile.js", () => {
    return jest.fn(() => {
      throw new Error("Parameter is not a number!");
    });
  });
  const kls = MyClass();
  kls.myMethod();
  expect(kls.errorMethod).toHaveBeenCalledTimes(1);
  expect(kls.successMethod).toHaveBeenCalledTimes(0);
});
test("should pass", () => {
  jest.doMock("./myFile.js", () => {
    return jest.fn(() => 1);
  });
  const kls = MyClass();
  kls.myMethod();
  expect(kls.errorMethod).toHaveBeenCalledTimes(0);
  expect(kls.successMethod).toHaveBeenCalledTimes(1);
});

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

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