デフォルトと名前付きエクスポートの両方を備えたES6モジュールがあります。
/** /src/dependency.js **/
export function utilityFunction() { return false; }
export default function mainFunction() { return 'foo'; }
2番目の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を使用して名前付きインポートとデフォルトインポートの両方をモックすることは可能ですか?モジュールから名前付き値とデフォルト値の両方をインポートし、両方をモックできる、私が望む結果を達成するために使用できる別の構文はありますか?
構文エラーがあります... myModule.jsのデフォルトのエクスポートからfunction
キーワードが省略されています。次のようになります。
import mainFunction, { utilityFunction } from './dependency';
export default function myModule() {
if (!utilityFunction()) return 2;
return mainFunction();
}
それ以外の方法でテストを実行する方法はわかりませんが、ローカルで試してみましたが、成功しました。
他の解決策は私にとってはうまくいきませんでした。これは私がやった方法です:
jest.mock('../src/dependency', () => ({
__esModule: true,
utilityFunction: 'utilityFunction',
default: 'mainFunction'
}));
それを行う別の方法:
jest.unmock('../src/dependency');
const myModule = require('../src/dependency');
myModule.utilityFunction = 'your mock'