我有一个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'
});
});
这个行为对我来说真的很奇怪,因为当仅模拟默认导入或命名导入中的一个时,这个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,是否可以模拟命名导入和默认导入?我是否可以使用不同的语法来实现我想要的结果,即从模块中导入命名和默认值,并能够模拟它们两个?
__esModule
属性中的驼峰式大小写——如果全部使用小写,则无法正常工作。 - Alexander Nied