Jest を使用して ES6 モジュールのインポートをモックするにはどうすればよいですか? 質問する

Jest を使用して ES6 モジュールのインポートをモックするにはどうすればよいですか? 質問する

私は私のES6モジュールは別のES6モジュールを特定の方法で呼び出します。ジャスミンこれはとても簡単です --

アプリケーションコード:

// myModule.js
import dependency from './dependency';

export default (x) => {
  dependency.doSomething(x * 2);
}

テストコード:

//myModule-test.js
import myModule from '../myModule';
import dependency from '../dependency';

describe('myModule', () => {
  it('calls the dependency with double the input', () => {
    spyOn(dependency, 'doSomething');

    myModule(2);

    expect(dependency.doSomething).toHaveBeenCalledWith(4);
  });
});

Jest で同等のものは何ですか? これはやりたいことがとても簡単なことのように感じますが、それを理解しようとすると頭を悩ませます。

私が行った最も近い方法は、importを に置き換えrequire、テスト/関数内に移動することです。どちらも私がやりたいことではありません。

// myModule.js
export default (x) => {
  const dependency = require('./dependency'); // Yuck
  dependency.doSomething(x * 2);
}

//myModule-test.js
describe('myModule', () => {
  it('calls the dependency with double the input', () => {
    jest.mock('../dependency');

    myModule(2);

    const dependency = require('../dependency'); // Also yuck
    expect(dependency.doSomething).toBeCalledWith(4);
  });
});

ボーナスポイントとして、内部の関数がデフォルトのエクスポートである場合に、全体が機能するようにしたいと思いますdependency.js。ただし、デフォルトのエクスポートをスパイすることは Jasmine では機能しないことはわかっています (少なくとも、機能させることはできませんでした)。そのため、Jest でも可能になることを期待していません。

ベストアンサー1

編集: 数年が経過しましたが、これはもはや正しい方法ではありません (おそらく、これまでもそうではありませんでした。申し訳ありません)。

インポートされたモジュールを変更するのは厄介であり、実行順序に応じてテストが成功または失敗するなどの副作用を引き起こす可能性があります。

歴史的な目的のため、この回答は元の形式のまま残していますが、実際にはjest.spyOnまたは を使用する必要がありますjest.mock。詳細については、jest のドキュメントまたはこのページの他の回答を参照してください。

元の回答は次のとおりです。


私は を含むハックを使用してこの問題を解決することができましたimport *。名前付きエクスポートとデフォルトエクスポートの両方で機能します。

名前付きエクスポートの場合:

// dependency.js
export const doSomething = (y) => console.log(y)
// myModule.js
import { doSomething } from './dependency';

export default (x) => {
  doSomething(x * 2);
}
// myModule-test.js
import myModule from '../myModule';
import * as dependency from '../dependency';

describe('myModule', () => {
  it('calls the dependency with double the input', () => {
    dependency.doSomething = jest.fn(); // Mutate the named export

    myModule(2);

    expect(dependency.doSomething).toBeCalledWith(4);
  });
});

またはデフォルトのエクスポートの場合:

// dependency.js
export default (y) => console.log(y)
// myModule.js
import dependency from './dependency'; // Note lack of curlies

export default (x) => {
  dependency(x * 2);
}
// myModule-test.js
import myModule from '../myModule';
import * as dependency from '../dependency';

describe('myModule', () => {
  it('calls the dependency with double the input', () => {
    dependency.default = jest.fn(); // Mutate the default export

    myModule(2);

    expect(dependency.default).toBeCalledWith(4); // Assert against the default
  });
});

おすすめ記事