Jest:使用默认导出和命名导出模拟ES6模块

tquggr8v  于 2023-01-22  发布在  Jest
关注(0)|答案(2)|浏览(185)

我有一个ES6模块,其中包含默认导出和命名导出:

/** /src/dependency.js **/

export function utilityFunction() { return false; }

export default function mainFunction() { return 'foo'; }

它正被第二个ES6模块使用:

/** /src/myModule.js **/

import mainFunction, { utilityFunction } from './dependency';

// EDIT: Fixed syntax error in code sample
// export default myModule() {
export default function myModule() {
    if (!utilityFunction()) return 2;
    return mainFunction();
}

我尝试使用Jest为myModule.js编写一个单元测试。但是当我尝试模拟命名导入和默认导入时,Jest似乎只模拟命名导入。它继续使用默认导入的实际实现,并且不允许我模拟它,即使在我调用.mockImplementation()之后。下面是我尝试使用的代码:

/** 
  * Trying to mock both named and default import. 
  * THIS DOESN'T WORK.
  */

/** /tests/myModule.test.js **/

import mainFunction, { utilityFunction } from '../src/dependency';
import myModule from '../src/myModule';

jest.mock('../src/dependency');

mainFunction.mockImplementation(() => 1);
utilityFunction.mockImplementation(() => true);

describe('myModule', () => {
    it('should return the return value of mainFunction when the result of utilityFunction is true', () => {
        expect(myModule()).toEqual(1); // FAILS - actual result is 'foo'
    });
});

这种行为在我看来很奇怪,因为当模拟JUST默认导入或JUST命名导入时,这个API工作正常。例如,在myModule.js只导入默认导入的情况下,这很容易做到:

/**
  * Trying to mock just the default import. 
  * THIS WORKS.
  */

/** /src/myModule.js **/

import mainFunction from './dependency';

// EDIT: Fixed syntax error in code sample
// export default myModule() {
export default function myModule() {
    return mainFunction();
}

/** /tests/myModule.test.js **/
// If only mainFunction is used by myModule.js

import mainFunction from '../src/dependency';
import myModule from '../src/myModule';

jest.mock('../src/dependency');
mainFunction.mockImplementation(() => 1);

describe('myModule', () => {
    it('should return the return value of mainFunction', () => {
        expect(myModule()).toEqual(1); // Passes
    });
});

在只使用命名的'utilityFunction'导出的情况下,模拟导入也很容易:

/**
  * Trying to mock both named and default import. 
  * THIS WORKS.
  */
/** /src/myModule.js **/

import { utililtyFunction } from './dependency';

// EDIT: Fixed syntax error in code sample
// export default myModule()
export default function myModule() {
    return utilityFunction();
}

/** /tests/myModule.test.js **/
// If only utilityFunction is used by myModule.js

import { utilityFunction } from '../src/dependency';
import myModule from '../src/myModule';

jest.mock('../src/dependency');
utilityFunction.mockImplementation(() => 'bar');

describe('myModule', () => {
    it('should return the return value of utilityFunction', () => {
        expect(myModule()).toEqual('bar'); // Passes
    });
});

是否可以使用Jest同时模拟命名和默认导入?是否可以使用不同的语法来实现我想要的结果,即从模块导入命名和默认值,并且能够模拟它们?

368yc8dk

368yc8dk1#

另一个解决方案对我不起作用。我是这样做的:

jest.mock('../src/dependency', () => ({
    __esModule: true,
    utilityFunction: 'utilityFunction',
    default: 'mainFunction'
  }));

另一种方法是:

jest.unmock('../src/dependency');

const myModule = require('../src/dependency');
myModule.utilityFunction = 'your mock'
pengsaosao

pengsaosao2#

您有语法错误... myModule.js的默认导出中省略了function关键字。应如下所示:

import mainFunction, { utilityFunction } from './dependency';

export default function myModule() {
    if (!utilityFunction()) return 2;
    return mainFunction();
}

我不知道你是怎么让测试运行的,但我只是在本地试用了一下,它通过了。

相关问题