reactjs 如何使用Jest监视默认导出函数?

von4xj4u  于 2022-12-18  发布在  React
关注(0)|答案(8)|浏览(197)

假设我有一个导出默认函数的简单文件:

// UniqueIdGenerator.js
const uniqueIdGenerator = () => Math.random().toString(36).substring(2, 8);

export default uniqueIdGenerator;

我会这样使用:

import uniqueIdGenerator from './UniqueIdGenerator';
// ...
uniqueIdGenerator();

我想在我的测试中Assert这个方法被调用了,同时保留了原来的功能。我想用jest.spyOn来做,但是,它需要一个对象和一个函数名作为参数。你怎么能用一种干净的方式来做呢?有一个类似的GitHub issue for jasmine给任何感兴趣的人。

tkqqtvp1

tkqqtvp11#

下面是一种在不修改导入(甚至根本不需要在测试中导入)的情况下为默认导出执行此操作的方法:

const actual = jest.requireActual("./UniqueIdGenerator");
const spy = jest.spyOn(actual, "default");
3z6pesqy

3z6pesqy2#

在某些情况下,您必须模拟导入才能发现默认导出:

import * as fetch from 'node-fetch'

jest.mock('node-fetch', () => ({
  default: jest.fn(),
}))

jest.spyOn(fetch, 'default')
nkoocmlb

nkoocmlb3#

仅模拟默认导出或任何其他导出,但将模块中的剩余导出保留为原始导出:

import myDefault, { myFunc, notMocked } from "./myModule";

jest.mock("./myModule", () => {
  const original = jest.requireActual("./myModule");
  return {
    __esModule: true,
    ...original,
    default: jest.fn(),
    myFunc: jest.fn()
  }
});

describe('my description', () => {
  it('my test', () => {
    myFunc();
    myDefault();
    expect(myFunct).toHaveBeenCalled();
    expect(myDefault).toHaveBeenCalled();
    
    myDefault.mockImplementation(() => 5);
    expect(myDefault()).toBe(5);
    expect(notMocked()).toBe("i'm not mocked!");
  })
});
bqf10yzr

bqf10yzr4#

对我有效的是Janne Annala的答案和OP自己的解决方案的组合。我想要测试的是helper方法是否被正确的参数调用,因为我已经为helper方法编写了一个测试,它对我随后的测试没有任何影响:

// myHelperMethod.js

export const myHelperMethod = (param1, param2) => { // do something with the params };
// someOtherFileUsingMyHelperMethod.js

import * as MyHelperMethod from '../myHelperMethod';

jest.mock('../myHelperMethod', () => ({
  myHelperMethod: jest.fn(),
}));

let myHelperMethodSpy = jest.spyOn(MyHelperMethod, 'myHelperMethod');

// ...
// some setup
// ...

test(() => {
  expect(myHelperMethodSpy).toHaveBeenCalledWith(param1, param2);
});
nxagd54h

nxagd54h5#

使用“default”作为spyOn函数中的第二个参数。

import * as MyHelperMethod from '../myHelperMethod';

jest.spyOn(MyHelperMethod, 'default');
oymdgrw7

oymdgrw76#

这里就更简单了。
使用jest模拟导出的模块“addDelay”(其中包含sleep函数)。

const { sleep } = require('../../src/utils/addDelay');

jest.mock('../../src/utils/addDelay', () => {
const delay = jest.requireActual('../../src/utils/addDelay');
return {
  ...delay,
  sleep: jest.fn(),
};});

测试如下所示,并检查sleep函数是否在1秒内调用,如arg所示。

test("Should delay 1 second if Okta user has no IDxM Roles", async () => {
    // GIVEN
    const MockSleep = sleep;

    // WHEN
    await getUser(req, res);
    
    // THEN
    expect(MockSleep).toHaveBeenCalledWith(1000);// sleep(1000): 1sec
});
g6baxovj

g6baxovj7#

我最终放弃了默认导出:

// UniqueIdGenerator.js
export const uniqueIdGenerator = () => Math.random().toString(36).substring(2, 8);

然后我可以这样使用和窥探它:

import * as UniqueIdGenerator from './UniqueIdGenerator';
// ...
const spy = jest.spyOn(UniqueIdGenerator, 'uniqueIdGenerator');

Some recommend将它们 Package 在一个常量对象中,并将其导出。我想您也可以使用类进行 Package 。
然而,如果你不能修改这个类,仍然有一个(不太好的)解决方案:

import * as UniqueIdGenerator from './UniqueIdGenerator';
// ...
const spy = jest.spyOn(UniqueIdGenerator, 'default');

eaf3rand

eaf3rand8#

也可以模拟导入并将原始实现作为模拟实现传递,如:

import uniqueIdGenerator from './UniqueIdGenerator'; // this import is a mock already

jest.mock('./UniqueIdGenerator.js', () => {
  const original = jest. requireActual('./UniqueIdGenerator')
  return {
     __esModule: true,
     default: jest.fn(original.default)
  }
})

test(() => {
  expect(uniqueIdGenerator).toHaveBeenCalled()
})

相关问题