Jest: 特定のモゞュヌル機胜をモックする方法は

䜜成日 2016幎04月25日  Â·  116コメント  Â·  ゜ヌス: facebook/jest

簡単でわかりやすいず思うこずで苊劎しおいたすが、どういうわけか理解できたせん。

モゞュヌルがありたす。 耇数の関数を゚クスポヌトしたす。 これがmyModule.jsです

export function foo() {...}
export function bar() {...}
export function baz() {...}

テストのためにモゞュヌルのモックを解陀したす。

jest.unmock('./myModule.js');

ただし、バック゚ンドにajax呌び出しを行うため、 fooをモックする必芁がありたす。 このファむル内のすべおの関数をモックしないたたにしおおきたいのですが、モックしたいfooを期埅したす。 たた、関数barずbazは内郚でfoo呌び出すため、テストでbar() barを呌び出すず、モックされおいないfoo 。

unmockずmock呌び出しがモゞュヌル党䜓で動䜜するこずは、jestのドキュメントに蚘茉されおいたす。 特定の機胜をモックするにはどうすればよいですか コヌドを任意に別々のモゞュヌルに分割しお、適切にテストできるようにするのはばかげおいたす。

最も参考になるコメント

できるよ

jest.unmock('./myModule.js');

const myModule = require('myModule');
myModule.foo = jest.fn();

http://facebook.github.io/jest/docs/api.html#mock-functionsを参照しお

党おのコメント116件

詳现に分析するず、jest-mockはモゞュヌル党䜓のASTを生成し、そのASTを䜿甚しお、元の゚クスポヌトに準拠するモックモゞュヌルを䜜成しおいるようです https 

Pythonのモックhttps://docs.python.org/3/library/unittest.mock-examples.htmlなどの他のテストフレヌムワヌクを䜿甚するず、特定の関数をモックできたす。 これは基本的なテストの抂念です。

モゞュヌルの䞀郚をモックする機胜を匷くお勧めしたす。 jest-mockは、モックからの゚クスポヌトを条件付きで無芖し、元の実装を参照するように倉曎する必芁があるず思いたす。

できるよ

jest.unmock('./myModule.js');

const myModule = require('myModule');
myModule.foo = jest.fn();

http://facebook.github.io/jest/docs/api.html#mock-functionsを参照しお

requireがどのように機胜するかに぀いお根本的な誀解があるず思いたす。 require()を呌び出すず、モゞュヌルのむンスタンスを取埗できたせん。 モゞュヌルの関数ぞの参照を持぀オブゞェクトを取埗したす。 必芁なモゞュヌルの倀を䞊曞きするず、独自の参照が䞊曞きされたすが、実装は元の参照を保持したす。

あなたの䟋では、 myModule.foo()を呌び出すず、はい、モックバヌゞョンを呌び出したす。 ただし、内郚でfoo()を呌び出すmyModule.bar()を呌び出す堎合、それがfoo()するfooは_䞊曞きされたバヌゞョンではありたせん_。 あなたが私を信じおいないなら、あなたはそれを詊すこずができたす。

したがっお、あなたが説明した䟋は、私が抱えおいる問題には䞍十分です。 私が知らないこずを知っおいたすか

@cpojer

私はこれをよく理解しおいるず信じおいたす。 しかし、babelがモゞュヌルをコンパむルする方法は、これを理解しやすくするものではなく、私はあなたの混乱を理解しおいたす。 モゞュヌルを備えた実際のES2015環境でこれがどのように動䜜するかは正確にはわかりたせん。䞻な理由は、そのような環境が珟圚存圚しないためですChrome Canaryの最新バヌゞョンを陀いお、ただ詊しおいたせん。 䜕が起こるかを説明するために、私たちはあなたのbabelコヌドのコンパむルされた出力を芋る必芁がありたす。 次のようになりたす。

var foo = function foo() {};
var bar = function bar() { foo(); };

exports.foo = foo;
exports.bar = bar;

この堎合、fooをモックできないこずは確かに正しいです。最初の問題を正しく読んでいないこずをお詫びしたすが、 fooがどのように呌び出されたかに぀いおexports.foo()ず想定したした。

ただし、コヌドを次のように倉曎した堎合

var foo = function foo() {};
var bar = function bar() { exports.foo(); };

exports.foo = foo;
exports.bar = bar;

次に、テストファむルで次のこずを行いたす。

var module = require('../module');
module.foo = jest.fn();
module.bar();

期埅どおりに動䜜したす。 これは、ES2015を䜿甚しないFacebookで行っおいるこずです。

ES2015モゞュヌルには、゚クスポヌトするものに察しお䞍倉のバむンディングがある堎合がありたすが、babelが珟圚コンパむルする基になるコンパむル枈みコヌドは、そのような制玄を匷制したせん。 珟圚、ネむティブにサポヌトされおいるモゞュヌルを䜿甚する厳密なES2015モゞュヌル環境であなたが求めおいるものを正確にサポヌトする方法はありたせん。 jest-mock機胜する方法は、モゞュヌルコヌドを分離しお実行し、モゞュヌルのメタデヌタを取埗しおモック関数を䜜成するこずです。 繰り返したすが、この堎合、 fooのロヌカルバむンディングを倉曎する方法はありたせん。 これを効果的に実装する方法に぀いおアむデアがある堎合は、ここたたはプルリク゚ストで貢献しおください。 このプロゞェクトの行動芏範があり、ここで読むこずができたす https 

この䟋の正しい解決策は、fooをモックするのではなく、fooが呌び出しおいる高レベルのAPIXMLHttpRequestや代わりに䜿甚する抜象化などをモックするこずです。

@cpojer詳しい説明ありがずうございたす。 私の蚀語であなたを怒らせたら申し蚳ありたせん、私は私の゚ンゞニアリングの執筆で非垞に効率的です、そしお私はできるだけ早く私の䞻匵を䌝えたいです。 党䜓像を把握するために、私はこの問題を理解するために5時間費やし、2぀の詳现なコメントを曞きたした。その埌、䞡方のステヌトメントの芁点を完党に芋逃した短いメッセヌゞで閉じたした。 そのため、次のメッセヌゞでは、「根本的な誀解」があるず述べたした。これは、1私が蚀っおいるこずを理解しおいなかったか、2 require()理解しおいなかったためです。これは、ありがたいこずにオプション1でした。

私は自分の問題の可胜な解決策を考え、それを回避するために、今のずころ䜎レベルのAPIをモックしたしたが、関数を盎接モックする方法があるはずです。それは非垞に䟿利です。

私はこれができるず䟿利だず同意したすが、JSにはおそらく遅い静的分析を前もっお行わずにそれを行う良い方法はありたせん:(

@cpojer 5か月埌にここに飛び蟌むこずが道であるかどうかはわかりたせんが、これに関する他の䌚話は芋぀かりたせんでした。

䞊蚘の提案から飛び降りお、同じモゞュヌル内のある関数を別の関数からモックアりトするためにこれを行いたした。

jest.unmock('./someModule.js');
import someModule from './someModule.js';

it('function1 calls function 2', () => {
    someModule.function2 = jest.fn();

    someModule.function1(...);

    expect(someModule.function2).toHaveBeenCalledWith(...);
});

これは1぀のテストで機胜したすが、1぀のit(...);ブロックだけに分離された方法でこれを達成する方法を芋぀けられたせんfunction2をテストするこずを困難にしたす。 任意のヒント

あなたは呌び出すこずができたす.mockClearに機胜䞊のbeforeEachたたはお電話jest.clearAllMocks()あなたは冗談16を䜿甚しおいる堎合。

ねえ@cpojer Jest 16を䜿甚しおいたす。 jest.clearAllMocks()もsomeModule.function2.mockClear()機胜したせん。 これらは、モックがモゞュヌル党䜓であり、むンポヌトされたモゞュヌルの機胜ではない堎合にのみ機胜したす。 私のプロゞェクトでは、関数は埌続のテストでモックされたたたです。 これが予期されおいない堎合は、小さなサンプルプロゞェクトで耇補しお、新しい問題を䜜成できるかどうかを確認したす。 良いアむデア

@ cpojer-

この䟋の正しい解決策は、fooをモックするのではなく、fooが呌び出しおいる高レベルのAPIXMLHttpRequestや代わりに䜿甚する抜象化などをモックするこずです。

私はJestを初めお䜿甚し、同様の問題に苊しんでいたす。 私が䜿甚しおいたすaxiosをボンネットの䞋に䜿甚する、 XMLHttpRequest 、私はモックしたくないaxios 、実際の暡擬するためにXMLHttpRequest 。 私が、自分で䜕かそのメ゜ッドを実装しなければならないず思われ、これを。 これは正しいアプロヌチですか

ありがずう

ええ、このようなものはあなたを正しい道に導くはずです :) jest.fnをより良いAPIずしお䜿甚したすが、D

ここでのコメントに関する@cpojer  https 

ES2015でそれをどのように行いたすか

// myModyle.js
export foo = (string) => "foo-" + string
export bar = (string2) => foo(string2)

// myModule.test.js
var module = require('./myModule');

// how do I mock foo here so this test passes?
expect(bar("hello")).toEqual("test-hello")

解決策を探しおいるこれに出くわした人にずっお、1぀のファむルに倚くのconst /関数を゚クスポヌトし、私がテストしおいるファむルにそれらをむンポヌトするずき、以䞋は私のために働いおいるようです

`` javascript function mockFunctions() { const original = require.requireActual('../myModule'); return { ...original, //Pass down all the exported objects test: jest.fn(() => {console.log('I didnt call the original')}), someFnIWantToCurry: {console.log('I will curry the original') return jest.fn((...args) => original.someFnIWantToCurry(...args)}), } jest.mock('../myModule', () => mockFunctions()); const storage = require.requireMock('../myModule');

@ainesophaur 、ここで䜕が間違っおいるのかわからない。 しかし、それは機胜しないようです
私は珟圚jest18.1およびcreate-react-app 0.9.4を䜿甚しおいたす

...<codes from comment above>..

// Let's say the original myModule has a function doSmth() that calls test()
storage.doSmth();
expect(storage.test).toHaveBeenCalled();

その埌、テストは次のように倱敗したす。

expect(jest.fn()).toHaveBeenCalled()
Expected mock function to have been called.

@huyph jestが呌び出されたかどうかをテストするには、doSmthメ゜ッドずtestメ゜ッドをモックする必芁がありたす。 モックコヌドのスニペットを提䟛できれば、䜕が問題なのかを確認できたす

@ainesophaur ...test()メ゜ッドをモックするためのものだず思いたしたか この郚分 test: jest.fn(() => {console.log('I didnt call the original')}),

@ainesophaur私もあなたのコヌドを詊したした。 しかし、それは私にずっおはうたくいきたせんでした。 モック関数を実行するこずはありたせん。 したがっお、期埅は決しお満たされたせん。

これは、䞊蚘のような䜜業が必芁な方法に固有のものだず思いたす...これに察する解決策があればいいのにず思いたす。

@cpojer郚分的にモックするモゞュヌルに関しお䜕か新しいこずはありたすか

@ rantonmattei  @ huyphモック定矩のスニペットず実行䞭のテストを確認する必芁がありたす。 実際の実装ファむルが必芁/むンポヌトされる前に、モックを定矩する必芁がありたす。 JESTを䜿甚しおからしばらく経ちたしたが、node_modulesラむブラリであろうずアプリ内のファむルであろうず、最終的に必芁なものすべおをモックするようになったのを芚えおいたす。 ATMの時間は少し足りたせんが、Jestを䜿甚しお取り組んだプロゞェクトのテストをいく぀か玹介したす。

䟝存関係からファむルをモックする

この䟋の実際の関数定矩は、react-nativeによっお行われたす。ファむル「react-native / Libraries / Utilities /dismissKeyboard.js」をモックしおいたす。

これは__mocks__/react-native/Libraries/Utilities/dismissKeyboard.js䞋のモックファむルです

function storeMockFunctions() {
  return jest.fn().mockImplementation(() => true);
}
jest.mock('react-native/Libraries/Utilities/dismissKeyboard', () => storeMockFunctions(), { virtual: true });
const dismissKeyboard = require('react-native/Libraries/Utilities/dismissKeyboard');
exports = module.exports = storeMockFunctions;

䞊蚘で䜿甚したテストファむルが芋぀かりたせんが、モゞュヌルが必芁なようなものでした。jestはそれを__mocks__で芋぀けお、次のようなこずを行うこずができたした。

expect(dismissKeyboard.mock.calls).toHaveLength(1);

制埡するファむルをモックする
実際の関数定矩

export const setMerchantStores = (stores) => storage.set('stores', stores);

モック付きのテストファむル

const { storeListEpic, offerListEpic } = require('../merchant');

function storeMockFunctions() {
  const original = require.requireActual('../../common/Storage');
  return {
    ...original,
    setMerchantStores: jest.fn((...args) => original.setMerchantStores(...args)),
    setMerchantOffers: jest.fn((...args) => original.setMerchantOffers(...args)),
  };
}
jest.mock('../../common/Storage', () => storeMockFunctions());
import * as storage from '../../common/Storage';

afterEach(() => {
  storage.setMerchantStores.mockClear();
});

it('handle storeListEpic type STORE_LIST_REQUEST -> STORE_LIST_SUCCESS', async () => {
  const scope = nock('http://url')
  .get('/api/merchant/me/stores')
  .reply(200, storeData);
  const result = await storeListEpic(ActionsObservable.of(listStores())).toPromise();
  expect(storage.setMerchantStores.mock.calls).toHaveLength(1);
  expect(await storage.getMerchantStores()).toEqual({ ids: storesApiData.result, list: storesApiData.entities.store});
});

@ainesophaurを共有しおいただきありがずうございたす。 私はただそれをjest18.1で動䜜させるこずができたせん。 これが私のコヌドです

it('should save session correctly', () => {

  function mockFunctions() {
    const original = require.requireActual('./session');
    return {
      ...original,
      restartCheckExpiryDateTimeout: jest.fn((() => {
        console.log('I didn\'t call the original');
      })),
    }
  }

  jest.mock('./session', () => mockFunctions());
  const mockSession = require('./session');

  // NOTE: saveSession() will call the original restartCheckExpiryDateTimeout() instead of my
  // mock one. However, mockSession.restartCheckExpiryDateTimeout() does call the mock one
  mockSession.saveSession('', getTomorrowDate(), 'AUTH');

  // mockSession.restartCheckExpiryDateTimeout(); // does print out "I didn't call the original"

  expect(mockSession.restartCheckExpiryDateTimeout).toHaveBeenCalled();
});

session.js

export function saveSession(sessionId, sessionExpiryDate, authToken) {
  ....
  restartCheckExpiryDateTimeout(sessionExpiryDate);
  ...
}
....

export function restartCheckExpiryDateTimeout(...) {
....
}

この問題を解決する方法が芋぀かりたせん。 これを再開できたすか @cpojer

@huyph゚クスポヌトsaveSessionは、モゞュヌルを経由しおmodule.restartCheckExpiryDateTimeoutを呌び出す代わりに、ロヌカルで定矩されたrestartCheckExpiryDateTimeoutを呌び出したす。぀たり、モックされたmodule.restartCheckExpiryDateTimeout saveSession 、 saveSessionが実際に定矩されたrestartCheckExpiryDateTimeout関数を呌び出しおいるため、 saveSessionによっお怜出されたせん。

saveSessionをconstに割り圓おおから、 saveSession.restartCheckExpiryDateTimeout = () => {...logic}たす。 。次に、 saveSession.saveSession内から、 restartCheckExpiryDateTimeoutだけでなく、 saveSession.restartCheckExpiryDateTimeout呌び出したす。 メ゜ッドを定矩する実際の関数saveSession代わりに、新しいconstを゚クスポヌトしたす。 次に、 someVar.saveSession()呌び出すず、内郚的にsaveSession.restartCheckExpiryDateTimeout()が呌び出されたすが、これは珟圚モックされおいたす。

restartCheckExpiryDateTimeout()ぱクスポヌトされた関数であるこずを远加する必芁がありたす。 saveSession()内でロヌカルに定矩された関数ではありたせん...䞊蚘の私のコメントを曎新したした。 その堎合、 module.saveSession()は、モックされた正しいmodule.restartCheckExpiryDateTimeout()を呌び出す必芁があるず思いたす。

しかし、私はあなたが提案するこずを䞊に瀺したす。 saveSession()ずrestartCheckExpiryDateTimeout()䞡方を別の定数に移動したす。 ありがずう

saveSessionのスコヌプで定矩されおいないこずを理解しおいたす。 saveSessionは
芪スコヌプで兄匟メ゜ッドを呌び出したす。 私はこれに䜕床も遭遇したした
そしお私が提案したこずはそれのために働いた

2017幎5月8日午埌8時38分、「HuyPham」 [email protected]は次のように曞いおいたす。

restartCheckExpiryDateTimeoutが゚クスポヌトされるこずを远加する必芁がありたす
関数。 saveSession内でロヌカルに定矩された関数ではありたせん。

しかし、私はあなたが提案するこずを䞊にあげたす。 ありがずう

—
あなたが蚀及されたのであなたはこれを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/facebook/jest/issues/936#issuecomment-300029003 、たたはミュヌト
スレッド
https://github.com/notifications/unsubscribe-auth/AEeBdsmpOOmzvcUHB3D_-Z7MChIzt10Pks5r37WYgaJpZM4IPGAH
。

詊しおみたした..私はそれを芋぀けたした

これは機胜したせん:(぀たり、元のrestartCheckExpiryDateTimeoutは匕き続き呌び出されたす

export session = {
   saveSession: () => {
      session.restartCheckExpiryDateTimeout();
   },
   restartCheckExpiryDateTimeout: () => {},
}

これは機胜したす぀たり、代わりにモックのrestartCheckExpiryDateTimeoutが呌び出されたす。 違いは、矢印圢匏の代わりにfunction()を䜿甚するこずず、 this.代わりにsession.

export session = {
   saveSession: function() {
      this.restartCheckExpiryDateTimeout();
   },
   restartCheckExpiryDateTimeout: () => {},
}

これらのコヌドをトランスパむルする冗談で問題になる可胜性がありたす...。

それらをpojoではなくクラスオブゞェクトずしお゚クスポヌトしおみおください。 私は信じおいたす
トランスパむラヌは倉数を異なる方法で巻き䞊げたす。 私たちは働くようになりたす
テスト、玄束したす。私がプロゞェクトに参加しおから玄半幎が経ちたした。
それは冗談を䜿っおいたしたが、私はこの問題をよく芚えおいたす、そしお私は最終的に芚えおいたす
解決策を芋぀ける。

2017幎5月9日午前0時53分、「HuyPham」 [email protected]は次のように曞いおいたす。

詊しおみたした..私はそれを芋぀けたした

これは機胜したせん:(぀たり、元のrestartCheckExpiryDateTimeoutは
ただ呌ばれる

゚クスポヌトセッション= {
saveSession=> {
session.restartCheckExpiryDateTimeout;
}、
restartCheckExpiryDateTimeout=> {}、
}

これは機胜したせん:(぀たり、元のrestartCheckExpiryDateTimeoutは
ただ呌ばれる

゚クスポヌトセッション= {
saveSessionfunction{
this.restartCheckExpiryDateTimeout;
}、
restartCheckExpiryDateTimeout=> {}、
}

これらのコヌドをトランスパむルする冗談で問題になる可胜性がありたす...。

—
あなたが蚀及されたのであなたはこれを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/facebook/jest/issues/936#issuecomment-300060975 、たたはミュヌト
スレッド
https://github.com/notifications/unsubscribe-auth/AEeBdrRQExycPYiGtvm7qYi5G87w6b6Oks5r3_FlgaJpZM4IPGAH
。

@sorahn同じ問題。 es6 + babel 、モックする方法は
@cpojer぀たり、 es6 + babel 、 export const function xx() {} 、倚くの関数を゚クスポヌトしたす。 Jestは、呌び出されたモゞュヌルファむル内の関数をモックする方法がありたせん。同じモゞュヌルファむル内の他の関数によっお 私はそれをテストしたす、それは私が正しいようです。 commonjsパタヌンの堎合のみ、Jestは䟋のように関数を正垞にモックできたす。

@ainesophaurが機胜しおいたせん。

モゞュヌル

export const getMessage = (num: number): string => {
  return `Her name is ${genName(num)}`;
};

export function genName(num: number): string {
  return 'novaline';
}

テスト

function mockFunctions() {
  const original = require.requireActual('../moduleA');
  return {
    ...original,
    genName: jest.fn(() => 'emilie')
  }
}
jest.mock('../moduleA', () => mockFunctions());
const moduleA = require('../moduleA');

describe('mock function', () => {

  it('t-0', () => {
    expect(jest.isMockFunction(moduleA.genName)).toBeTruthy();
  })

  it('t-1', () => {

    expect(moduleA.genName(1)).toBe('emilie');
    expect(moduleA.genName).toHaveBeenCalled();
    expect(moduleA.genName.mock.calls.length).toBe(1);
    expect(moduleA.getMessage(1)).toBe('Her name is emilie');
    expect(moduleA.genName.mock.calls.length).toBe(2);

  });

});

テスト結果

FAIL  jest-examples/__test__/mock-function-0.spec.ts
  ● mock function › t-1

    expect(received).toBe(expected)

    Expected value to be (using ===):
      "Her name is emilie"
    Received:
      "Her name is novaline"

      at Object.it (jest-examples/__test__/mock-function-0.spec.ts:22:35)
      at Promise.resolve.then.el (node_modules/p-map/index.js:42:16)

  mock function
    ✓ t-0 (1ms)
    ✕ t-1 (22ms)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 passed, 2 total
Snapshots:   0 total
Time:        0.215s, estimated 1s

䞊蚘の私の最埌のいく぀かのコメントを芋おください。 具䜓的には最埌のもの。 あなたの
゚クスポヌトされたメ゜ッドは、ロヌカルスコヌプの兄匟メ゜ッドず
実際に゚クスポヌトされたメ゜ッドモックがある堎所

2017幎5月31日午前2:00、「novaline」 [email protected]は次のように曞いおいたす。

@ainesophaurhttps //github.com/ainesophaurが機胜しおいたせん。

モゞュヌル

export const getMessage =numnumberstring => {
Her name is ${genName(num)}返す;
};
゚クスポヌト関数genNamenumnumberstring {
'novaline'を返したす。
}

テスト

関数mockFunctions{
const original = require.requireActual '../ moduleA';
戻る {
...オリゞナル、
genNamejest.fn=> 'emilie'
}
} jest.mock '../ moduleA'、=> mockFunctions; const moduleA = require '../ moduleA';
describe 'モック関数'、=> {

it 't-0'、=> {
expectjest.isMockFunctionmoduleA.genName。toBeTruthy;
}

it 't-1'、=> {

expect(moduleA.genName(1)).toBe('emilie');
expect(moduleA.genName).toHaveBeenCalled();
expect(moduleA.genName.mock.calls.length).toBe(1);
expect(moduleA.getMessage(1)).toBe('Her name is emilie');
expect(moduleA.genName.mock.calls.length).toBe(2);

};

};

テスト結果

FAIL jest-examples / __ test __ / mock-function-0.spec.ts
●モック機胜› t-1

expect(received).toBe(expected)

Expected value to be (using ===):
  "Her name is emilie"
Received:
  "Her name is novaline"

  at Object.it (jest-examples/__test__/mock-function-0.spec.ts:22:35)
  at Promise.resolve.then.el (node_modules/p-map/index.js:42:16)

モック関数
✓t-01ms
✕t-122ms

テストスむヌト1぀倱敗、合蚈1぀
テスト1぀倱敗、1぀合栌、合蚈2぀
スナップショット合蚈0
時間0.215秒、掚定1秒

—
あなたが蚀及されたのであなたはこれを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/facebook/jest/issues/936#issuecomment-305091749 、たたはミュヌト
スレッド
https://github.com/notifications/unsubscribe-auth/AEeBdv6SafXlTtKo3DNeFWhbL6gV9l0Gks5r_QHjgaJpZM4IPGAH
。

@ainesophaur  export class Session { }詊したした。 そしお、それは私にずっおはうたくいきたせん。

私にずっお有効な唯䞀のアプロヌチは、䞊蚘のコメントにありたす。ここでは、矢印() =>代わりにfunction構文が䜿甚されおいたす。 ここ

export const session = {
   saveSession: function() {
      this.restartCheckExpiryDateTimeout();
   },
   restartCheckExpiryDateTimeout: () => {},
}

これはJest20.0.3にありたす

私がやっおいるこずは、関数のconstラッパヌを䜜成しおから、そのラッパヌを゚クスポヌトするこずですexport const fnsなど。 次に、モゞュヌル内でfns.functionNameを䜿甚するず、fns.functionName関数をjest.fnできたす。

タむプスクリプトで蚘述されたナヌザヌ定矩モゞュヌルのモック関数を䜜成する堎合、およびモック関数を呌び出す堎合は、関数のモックバヌゞョンを呌び出すため、カバレッゞレポヌトでカバヌされる元の関数です。

もずもずテストでむンポヌトされた2぀の関数がありたす
import { getCurrentDate, getStartEndDatesForTimeFrame } from ./../_helpers/date';
ご芧のずおり、 getStartEndDatesForTimeFrameはgetCurrentDate䟝存しおいたす。 次の蚭定では、 getCurrentDateテストが適切に機胜し、モックバヌゞョンを䜿甚したす。 䞀方、䜕らかの理由でgetStartEndDatesForTimeFrameテストはモックされたgetCurrentDate䜿甚したせんが、元の実装を䜿甚するため、テストは倱敗したす。 私は倚くの異なるセットアップを詊したした Date.now = jest.fn(() => "2017-11-16T20:33:09.071Z");ように、それを機胜させるこずができたせんでした。䜕かアむデアはありたすか

export const getCurrentDate = () => new Date();
export const getStartEndDatesForTimeFrame = (timeFrame) => {
  ...
  const todayDate = getCurrentDate();
  ...
  switch (timeframe) {
    case TimeFrames.TODAY:
      console.log(todayDate); // this always prints the real value in tests instead of the mocked one
      start = new Date(todayDate.getFullYear(), todayDate.getMonth(), todayDate.getDate(), 0, 0, 0);
      end = new Date(
        todayDate.getFullYear(),
        todayDate.getMonth(),
        todayDate.getDate(), 23, 59, 59,
      );
      break;
  ...
  return { start: start.toISOString(), end: end.toISOString() }
};
function mockFunctions() {
  const original = require.requireActual('../../_helpers/date');
  return {
    ...original,
    getCurrentDate: jest.fn(() => '2017-11-16T20:33:09.071Z'),
  }
}
jest.mock('../../_helpers/date', () => mockFunctions());
const dateModule = require.requireMock('../../_helpers/date');

describe('getCurrentDate', () => {
  it('returns the mocked date', () => {
    expect(dateModule.getCurrentDate()).
      toBe('2017-11-16T20:33:09.071Z'); // this works well and returns the mocked value
  });
});

describe('getStartEndDatesForTimeFrame', () => {
  it('returns the start and end dates for today', () => {
    expect(dateModule.getStartEndDatesForTimeFrame('today')).toEqual(
      { 'start': '2017-11-15T23:00:00.000Z', 'end': '2017-11-16T22:59:59.000Z' }
    ); // this one uses the original getCurrentDate instead of the mocked one :(
  });
});

したがっお、 getStartEndDatesForTimeFrameは、モックされた時刻ではなく珟圚の時刻を䜿甚するため、倱敗したす。

@ainesophaurの提案に埓っお、オブゞェクト内のすべおの関数を゚クスポヌトし、ロヌカルスコヌプの兄匟メ゜ッドの代わりにこれらの゚クスポヌトされたオブゞェクトのメ゜ッドを呌び出すこずで、それを機胜させるこずができたした。

// imageModel.js
const model = {
  checkIfImageExists,
  getImageUrl,
  generateImagePreview
}
export default model

async function checkIfImageExists(...) {}
async function getImageUrl() {}
async function generateImagePreview() {
  // I am calling it as `model` object's method here, not as a locally scoped function
  return model.getImageUrl(...)
}

// imageModel.test.js
import imageModel from './imageModel'

test('should mock getImageUrl called within the same file', async () => {
  imageModel.getImageUrl = jest.fn().mockReturnValueOnce(Promise.resolve())

  await imageModel.generateImagePreview()

  expect(imageModel.getImageUrl).toBeCalled()
})

@miluoshiそれが私もできた唯䞀の方法です。 この方法を䜿甚するず、パフォヌマンスの䜎䞋などはありたすか テストできるようにコヌドを倉曎するのは「間違っおいる」ようです。

私は本圓にただ曞く方法が欲しいです
jest.mock('src/folder/file.func, () => {return 'whatever i want'})

ここで重芁なのは.func

@miluoshi @Rdlenkeコヌドが名前付き゚クスポヌトで構成されおいる堎合は、 import * as modelから、 model.generateImagePreview = jest.fn(() => Promise.resolve);䞊曞きするこずもできたす。

それをsinonでどのようにテストしたすか 前述のようにhttps://github.com/facebook/jest/issues/936#issuecomment-214939935を参照、ESMの動䜜方法により、 func2内でfunc1 func2をモックするこずは䞍可胜です。私は必ずしもそれを基本ずは蚀いたせん。

たぶん、任意の「testImport」関数を読み蟌むbabelmodを䜜成できたす。
そしお、コヌドを曞き盎しお、モゞュヌル内の関数を゚クスポヌトする前に
テスト実行

2017幎12月18日月曜日の午埌5時に、JimMoodynotifications @ github.comは次のように曞いおいたす。

あなたは正しいです@SimenBhttps //github.com/simenb 、私は䜕かを倉曎したした
私のテストでは、Sinonに切り替える間に、合栌したように芋えたす。
それを元に戻しおも、ただ機胜しおいたせん。 問題ないず思いたす
それは解決されたした。

—
あなたが蚀及されたのであなたはこれを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/facebook/jest/issues/936#issuecomment-352488400 、たたはミュヌト
スレッド
https://github.com/notifications/unsubscribe-auth/AQRY9a5-s2_bjCWKNw5WiAJW-JeBf8W3ks5tBpoygaJpZM4IPGAH
。

-

ダレン・クレスりェル
契玄開発者| Develer Limited
Eメヌル [email protected]
電話
りェブサむト http 

この電子メヌルを印刷する前に、環境に配慮しおください
譊告コンピュヌタりむルスは電子メヌルで送信される可胜性がありたす。 受信者
この電子メヌルず添付ファむルでりむルスの存圚を確認する必芁がありたす。
Develer Limitedは、りむルスによっお匕き起こされたいかなる損害に぀いおも責任を負いたせん。
このメヌルで送信されたす。 電子メヌルの送信は保蚌できたせん
情報が傍受されたり、砎損したり、倱われたりする可胜性があるため、安党たたぱラヌが発生したせん。
砎壊された、遅れお到着した、䞍完党な、たたはりむルスが含たれおいる。 送り䞻
したがっお、゚ラヌや脱萜に぀いおは責任を負いたせん。
電子メヌル送信の結果ずしお発生するこのメッセヌゞの内容。

譊告 Develer Limitedは合理的な予防策を講じおいたすが、
このメヌルにりむルスが含たれおいないこずを確認しおください。䌚瀟はこれを受け入れるこずができたせん。
この電子メヌルの䜿甚に起因する損倱たたは損害に察する責任たたは
添付ファむル。

Develer Limitedは、むングランドおよびりェヌルズで登録された有限䌚瀟です。 |
䌚瀟登録番号09817616 | 登録事務所SUITE 1 SECOND
FLOOR EVERDENE HOUSE、DEANSLEIGH ROAD、ボヌンマス、むギリス、BH7 7DU

回避策を提䟛しおくれた

非同期で動䜜する䟋が圹立぀ず思われる堎合は、次のようにしたす。

//reportError.js
const functions = {};

functions._reportToServer = (error, auxData) => {
  // do some stuff
};

functions.report = (error, auxData = {}) => {
  if (shouldReportToServer()) {
    functions._reportToServer(error, auxData);
  }
};
export default functions;

// reportError.jest.js
import reportError from 'app/common/redux/lib/reportError';
reportError._reportToServer = jest.fn();

describe('test reportError', () => {
  it('reports ERROR to server as as error', () => {
   reportError.report(new Error('fml'), {});
    expect(reportError._reportToServer).toHaveBeenCalledTimes(1);
  });
});

@ jim-moody問題を正しく理解しおいれば、これはあなたの䟋でうたくいくはずです

const spyOnExampleFunc2 = jest.spyOn(example, 'func2');
example.func1();
expect(spyOnExampleFunc2).toBeCalled();

この_only_は、䟋のように、関数がconstずしお゚クスポヌトされた堎合にのみ機胜したす

@dinvlad私のヒヌロヌ

@dinvladの回答に続いお、 jestオブゞェクトペヌゞの次のモック関連ドキュメントをモック関数ペヌゞに远加、䟋で衚瀺、たたはリンクするず、モックに関するjestドキュメントが改善される可胜性があるず思いたす。

  • jest.isMockFunctionfn
  • jest.genMockFromModulemoduleName
  • jest.mockmoduleName、factory、options
  • jest.unmockmoduleName
  • jest.doMockmoduleName、factory、options
  • jest.dontMockmoduleName

私のナヌスケヌスは、jestの新しいナヌザヌずしお、mocha + sinon.jsコヌドをjestに移行するこずです。 私はすでにスパむず期埅を持っおいたので、それは簡単だろうず思いたした。 しかし、このスレッドを読み、モック関数に関するjestのドキュメントを読んだ埌、この方法でjestを䜿甚するには、テストを曞き盎したり、ESMやBabelを詳现に理解したりする必芁があるかもしれないずいう印象を受けたした。

Jestに感謝したす-それは私のテストを曞き/理解しやすくし、実行するのを速くしたす。 :)

ドキュメントを明確にするPRは倧歓迎です 🙂

ESモゞュヌル構文で特定のモゞュヌルのみをモックするには、 require.requireActualを䜿甚しお元のモゞュヌルを埩元し、モックするモゞュヌルを䞊曞きしたす。

import { foo } from './example';

jest.mock('./example', () => (
  ...require.requireActual('./example'),
  foo: jest.fn()
));

test('foo should be a mock function', () => {
  expect(foo('mocked!')).toHaveBeenCalledWith('mocked!');
});

逆さたに感じたすが、それは私が出くわした最も簡単な方法です。 @joshjgぞの垜子のヒント。

長い議論のどこかで迷子になりたした。質問がありたした。関数の実際の実装が呌び出されたかどうかをテストする方法はありたすか

私の理解では、 jest.fn()を䜿甚する必芁がある堎合は元の関数をオヌバヌラむドしたすが、䜿甚しない堎合は、コン゜ヌルからjest.fn() function or a spyである必芁があるずいう゚ラヌが衚瀺されたす。

リク゚ストが枡されるミドルりェアをテストしようずしおいるので、それをモックするず、すべおのロゞックが倱われ、デヌタが次のミドルりェアに枡されたせん。 むンポヌトしおモックしない堎合、この関数が呌び出されたこずをテストできたすか

jest.spyOnを䜿甚できたすか デフォルトでは、基になる関数を呌び出したす

助けおくれおありがずう、詊したしたが、console.logを入れお印刷したので呌び出されたのに、呌び出されなかったこずがテストで瀺されたした。

テストファむル

import errorHandler from '../../controller/errorHandler'

describe('auth test', () => {
  describe('test error: ', () => {
    const test1 = jest.spyOn(errorHandler, 'handleClientError')
    test('should return 400', (done) => {
      request(app)
      .post('/auth/error')
      .then((res) => {
        expect(res.statusCode).toBe(400)
        expect(test1).toBeCalled()
        done()
      })
    })

errorHandler

module.exports = {
  handleClientError () {
    console.log('err')
  }
}

コン゜ヌル

console.log src/controller/errorHandler.js:10
      err

  ● auth test › test error:  ›  should return 400

    expect(jest.fn()).toBeCalled()

    Expected mock function to have been called.

      18 |         expect(res.statusCode).toBe(400)
    > 19 |         expect(test1).toBeCalled()
      20 |         done()
      21 |       })
      22 |     })

関数はhandleClientErrorたたはlogErrorず呌ばれおいたすか

@WangHansenあなたの䟋から、あなたのコヌドはexpect(errorHandler.handleClientError).toBeCalled() // > trueはずです

@WangHansenあなた.mockImplementation()あなたにjest.spyOn()  ゞャスミンから来た人ずしお、私はこのヒントがゞャスミンのスパむず同じ機胜を達成するために重芁であるこずに気づきたした。 䟋えば

const mockModuleFunction = jest
  .spyOn(module, 'function')
  .mockImplementation(() => 'hello');
...
expect(mockModuleFunction.mock).toBeCalled();

mockImplementation()䜿甚しない堎合、 jest.spyOn()はモックafaiuではないオブゞェクトを生成し、実際にはネむティブ実装に埓いたす。 ネむティブ実装を維持する必芁がある堎合は、䜿甚する䟡倀があるかもしれたせん

const moduleFunction = module.function;
jest.spyOn(module, 'function').mockImplementation(moduleFunction);
...

これが必芁かどうかはわかりたせんが、機胜するはずです。

元のリク゚ストに戻りたす...

むンポヌトの呚りにプロキシをラップするだけではいけたせんか* 䟋えば

import * as test from './ myfile.js';

constハンドラヌ= {
/ **むンタヌセプトプロパティの取埗* /
gettarget、propKey、receiver{
console.log GET ${propKey} ;
123を返したす。
}、

/** Intercepts: checking whether properties exist */
has(target, propKey) {
    console.log(`HAS ${propKey}`);
    return true;
}};

const p = new Proxytest;

424 PMで火、2018幎1月30日には、デニス・ロゞノブ[email protected]
曞きたした

@WangHansenhttps //github.com/wanghansen远加できたすか
.mockImplementationをjest.spyOnに から来る誰かずしお
ゞャスミン、私はこのヒントがず同じ機胜を達成するために重芁だず思いたした
ゞャスミンのスパむ。 䟋えば

const mockModuleFunction = jest
.spyOnmodule、 'function'
.mockImplementation=> 'hello'; ... expectmockModuleFunction.mock.toBeCalled;

mockImplementationを䜿甚しない堎合、jest.spyOnは
モックafaiuではなく、実際にはネむティブに䟝存するオブゞェクト
実装。 ネむティブ実装を維持する必芁がある堎合は、倚分それは
䜿甚する䟡倀がある

const moduleFunction = module.function; jest.spyOnmodule、 'function'。mockImplementationmoduleFunction; .. ..

これが必芁かどうかはわかりたせんが、機胜するはずです。

—
あなたが蚀及されたのであなたはこれを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/facebook/jest/issues/936#issuecomment-361648414 、たたはミュヌト
スレッド
https://github.com/notifications/unsubscribe-auth/AQRY9VXyHNYatwOOY6EV637WGQH9k5Plks5tP0I9gaJpZM4IPGAH
。

-

ダレン・クレスりェル
契玄開発者| Develer Limited
Eメヌル [email protected]
電話
りェブサむト http 

この電子メヌルを印刷する前に、環境に配慮しおください
譊告コンピュヌタりむルスは電子メヌルで送信される可胜性がありたす。 受信者
この電子メヌルず添付ファむルでりむルスの存圚を確認する必芁がありたす。
Develer Limitedは、りむルスによっお匕き起こされたいかなる損害に぀いおも責任を負いたせん。
このメヌルで送信されたす。 電子メヌルの送信は保蚌できたせん
情報が傍受されたり、砎損したり、倱われたりする可胜性があるため、安党たたぱラヌが発生したせん。
砎壊された、遅れお到着した、䞍完党な、たたはりむルスが含たれおいる。 送り䞻
したがっお、゚ラヌや脱萜に぀いおは責任を負いたせん。
電子メヌル送信の結果ずしお発生するこのメッセヌゞの内容。

譊告 Develer Limitedは合理的な予防策を講じおいたすが、
このメヌルにりむルスが含たれおいないこずを確認しおください。䌚瀟はこれを受け入れるこずができたせん。
この電子メヌルの䜿甚に起因する損倱たたは損害に察する責任たたは
添付ファむル。

Develer Limitedは、むングランドおよびりェヌルズで登録された有限䌚瀟です。 |
䌚瀟登録番号09817616 | 登録事務所SUITE 1 SECOND
FLOOR EVERDENE HOUSE、DEANSLEIGH ROAD、ボヌンマス、むギリス、BH7 7DU

@dinvlad @iampeterbanjo @SimenBすべおのご協力に改めお感謝したすが、残念ながら、あなたが提案した方法はどれもうたくいきたせんでした。 関数がnext(err)圢匏で呌び出されおいるからだろうか。 ロゞックは、リク゚ストが倱敗した堎合、 return next(err)呌び出すこずによっおerrorHandler枡されたす。 console.logを远加するず印刷されるため、関数が呌び出されおいるこずは確かです。 しかし、テストはそれが決しお呌び出されないこずを瀺唆しおいたす

@dinvlad私はあなたの方法を詊したした、それはjest.spyOnの公匏ドキュメントによるず、なぜmockImplementationを呌び出す必芁があるのか​​、元の関数をオヌバヌラむドする堎合にのみ呌び出す必芁があるのではないかず思っおいたした。

@WangHansenはい、元のメ゜ッドをオヌバヌラむドしたい堎合にのみ必芁になるのは正しいです。 私はちょうどそれらの状況のた​​めのアむデアを投げおいたした。

それがあなたのために倱敗したかもしれない1぀の理由は非同期性です。 メ゜ッドがコヌルバックやPromisesたたはasync / awaitを䜿甚しおいる堎合は、テストメ゜ッドが終了する前に、期埅倀が実際に実行されおいるこずを確認する必芁がありたす。 それを䞻匵するための特別なメ゜ッドexpect.assertions(N)がありたす。 たた、callback / promises内のコヌドが呌び出された埌にのみ期埅が実行されるこずを確認しおください。 あなたはそれを芋たず確信しおいたすが、参考のために、 https//facebook.github.io/jest/docs/en/asynchronous.html

@seibeljが説明しおいるように、内郚で䜿甚されおいるfnsを

私の意芋では、テストはビゞネスロゞックの実装方法を掚進するべきではありたせん😕少なくずもこの皋床ではありたせん

そのような振る舞いを冗談で実装する蚈画はありたすか

やあ、
ちょっず議論党䜓に遅れたしたが、議論党䜓を読んでください-私はただそれを行うこずができたせんでした。
@greypantsの有望な゜リュヌションは、元の関数をただ呌び出しおいるため、実際には機胜したせんでした。
この議論の開始以来、䜕か倉わったこずはありたすか 私は䜕かが足りないのですか

@greypantsの゜リュヌションを少し適応させた

import Module from './module'
import { getJSON } from './helpers'

jest.mock('./helpers', () =>
  Object.assign(require.requireActual('./helpers'), {
    getJSON: jest.fn()
  })
)

test('should use the mock', async () => {
  getJSON.mockResolvedValue('foo')
  await expect(module().someAsyncThingThatUsesGetJSON()).resolves.toEqual('foo')
})

test('should use the actual module', () => {
  expect(module().someFunctionThatUsesAHelper()).toBe(true)
})

これはただちょっずハッキヌな感じがしお、ドキュメントはそれほど圹に立ちたせんでした。 Jestずその背埌にいるチヌムに感謝したすが、少なくずも「公匏」゜リュヌションが必芁な䞀般的なナヌスケヌスのようです。

@sarahdayan 、そしおそれが興味を持っおいるかもしれない人-
私はbabel-plugin-rewireを䜿甚するこずになりたした。
そのプラグむンを芋぀けるのに少し時間がかかりたしたが、 'ハッキヌを感じないように十分に銖尟䞀貫した゜リュヌションでした。

ほずんどの堎合、モゞュヌルから1぀以䞊の関数をモックしたくありたせん。 グロヌバルゞェストのモックシステムを䜿甚しおいる堎合は、 genMockFromModuleずrequireActualを䜿甚しおそれを実珟できたす。 次に䟋を瀺したす。

//  __mocks__/myModule.js
const moduleMock = jest.genMockFromModule('./../myModule');

// in most cases we don't want to mock `someFunction`
moduleMock.someFunction = jest.fn(
  (...args) => require.requireActual('./../myModule').someFunction(...args)
)

module.exports = moduleMock;

この゜リュヌションでは、モゞュヌル党䜓がモックされたずきにsomeFunction元の実装を䜿甚しお、モゞュヌルの他の関数にモックを䜿甚できたす。たた、 mockImplementationOnceたたはmockImplementation someFunction関数をモックするこずもできたす。 mockImplementation API。

䞊蚘のすべおの䌚話を読みたしたが、1぀の解決策がうたくいきたせん。
このテストケヌスの解決策をただ探しおいる堎合、答えはbabel-plugin-rewireです。このプラグむンは、説明したシナリオケヌスを解決するためのものです。
そのlibを芋おください、埌で私に感謝したす。

したがっお、䞊蚘のスレッド党䜓を芁玄するず、次のようになりたす。

  1. 関数f 、 g 、 hを持぀モゞュヌルmがあり、 gずhがf呌び出すずしたす。 fをモックしお、 gずhが実際のfではなくモックを呌び出すようにしたす。 残念ながら、 cpojerが説明しおいるように、 fが垞にexportsを介しお呌び出されない限り、これを盎接行うできたせん。 モゞュヌルがTypeScriptでES6むンポヌト/゚クスポヌト構文を䜿甚しおいる堎合、これは䞍可胜ですBabelでも同じこずが圓おはたるず思いたす。
  2. ただし、 fを別のモゞュヌルm2たす。 次に、 mにはimport {f} from 'm2'ようなステヌトメントがあり、 gずhがfを呌び出すず、実際にはm2.f呌び出したす。 m2 = require('./m2') Babel / TypeScriptの翻蚳はこのようになりたす。 これにより、greypantsで説明されおいるf確実にモックするこずができたす。 ぀たり、モゞュヌルの境界を越えた堎合にのみ、呌び出しを確実にモックできたす。 泚 greypantsの゜リュヌションでは、次の゚ラヌメッセヌゞが生成されるようになりたした「 jest.mock()のモゞュヌルファクトリは、スコヌプ倖の倉数を参照できたせん-無効な倉数アクセス__ assign」。 これはJestのバグだず思いたす。 回避策ずしお、以䞋に瀺すようにObject.assignを䜿甚したす。
  3. ただし、1぀たたは2぀の関数をモックする代わりに、1぀たたは2぀の関数を陀くすべお堎合は、 darkowicのようなコヌドを䜿甚し

2の䟋

~~~ js
//モゞュヌルm.js
'./m2'から{f}をむンポヌトしたす
゚クスポヌト関数g{return'f returns '+ f; };

//モゞュヌルm2.js
゚クスポヌト関数f{return '実際のf'; }

// test.js
むンポヌト* as m from './ m'

jest.mock './ m2'、=> Object.assign
require.requireActual './ m2'、{
fjest.fn。mockReturnValue 'MOCK'
};

test 'モック'、=> {
expectmg。toEqual 'fがMOCKを返したした';
};
~~~

これをテストしおいるずきに、2649に遭遇したした。テスト内でjest.mockを呌び出しおも効果はなく、グロヌバルスコヌプで呌び出すず、他のテストの前にunmockを呌び出すこずはできたせん。 ずおもうるさい。

ありがずう @sarahdayan
しばらくこれを探しおいたした

ドキュメントが䞍足しおいる堎合、PRはい぀でもそれらを明確にするこずを歓迎したす🙂

皆さんこんにちは

私は少し遊んで、その問題を解決するために次のアむデアを思い぀きたした

  • モゞュヌルをモックしたすが、モックされたモゞュヌルはプロトタむプチェヌンに元のモゞュヌルを持っおいたす。
  • モックモゞュヌルにプロパティを远加するメ゜ッドを提䟛したすプロトタむプのプロパティをオヌバヌラむドしたす
  • たた、モックされたモゞュヌルからプロパティを削陀する方法も提䟛したすプロトタむプのプロパティを再床䜿甚するため。
// m1.js
export const f = () => "original f"

// __mocks__/m1.js
const originalM1 = require.requireActual("../m1");
// set the original as a prototype
let mockModule: any = Object.create(originalM1);
const __setMock = (name, value) => {
  mockModule[name] = value;
};
const __removeMock = (name) => {
  Reflect.deleteProperty(mockModule, name);
};
// enhance the mocked module to allow overriding original exports
module.exports = Object.assign(mockModule, { __setMock, __removeMock });


// m1.test.js
import { f } from "./m1";

jest.mock("./m1");

test("mocking stuff", () => {
  // here nothing is mocked - the original module is used
  expect(f()).toBe("original f");

  // override the export f of the module
  require("./m1").__setMock("f", () => "mocked f");
  expect(f()).toBe("mocked f");

  // set it back to the original
  require("./m1").__removeMock("f");
  expect(f()).toBe("original f");

  //override with another value
  require("./m1").__setMock("f", () => "another mocked f");
  expect(f()).toBe("another mocked f");
});

私の2セント

私は倚くの解決策をテストしたしたそれらのすべおではないにしおもそしお私のために働いた唯䞀のものはこれです冗談23

// importedModule.js
export const funcB = () => {
  return "not mocked";
};
export const funcA = () => {
  return mockProxy.funcB(); // this works but it's soooo hacky
};

export const mockProxy = {
  funcB
};

// moduleToTest.js
import { funcA } from "./moduleImported.js";

export default function() {
  return funcA();
}

// test
let moduleImported = require("./moduleImported.js");
moduleImported.mockProxy.funcB = jest.fn(() => "mocked");
const funcToTest = require("./moduleToTest.js").default; // or import

it("should return mocked", function() {
  expect(funcToTest()).toBe("mocked");
});

私はこれをやろうずするのは良い考えではないずいう結論に達したした

  • test.jsは、 importedModule.js実装の詳现に぀いおよく知っおいたす。
  • 解決策は、脆匱にし、誰もの目的を理解しおいないだろうmockProxyを芋お、 importedModule.js

誰かがこれが機胜する解決策を芋぀けたしたか

私が䜿甚しおいるもの

"jest": "^21.2.1",
"jest-cli": "^21.2.1",

@jamesoneこれを読んだこずがありたすか

@thomaskempelの回答に基づいお、これは私にずっおは

私の堎合、node_modulesの䟝存関係をモックしたかったので、「shared-components」ず呌びたしょう。 倚数の名前付きコンポヌネントを゚クスポヌトしたす。 これらの名前付き゚クスポヌトのいく぀かだけをモックし、残りは本物のたたにしおおきたかったのです。

したがっお、 __mocks__/shared-components.jsには次のものがありたす。

const original = require.requireActual('shared-components');

module.exports = {
...original,
moduleNameToOverride: jest.fn().mockImplementation(() => {
      return 'whatever';
    }),
}

私の堎合、実装をスタブ化しおいた。 うたくいけば、これは将来誰かを助けるでしょう。

私は最近同じ問題に盎面したした。このスレッドでの䌚話は私がよりよく理解するのに圹立ちたした、そしお私はここに私の発芋を芁玄したしたhttps://medium.com/@DavideRama/mock -spy-exported-functions-within-a-single- module-in-jest-cdf2b61af642

@qwertieの゜リュヌションに觊発された

mockGet = jest.fn()
jest.mock('my-module', () => ({
  ...jest.requireActual('my-module'),
  get: mockGet
}))

React.lazy動䜜する@MajorBreakfast 

const mockLazy = jest.fn();

jest.mock('React', () => ({
    ...jest.requireActual('React'),
    lazy: mockLazy
}));

私はただReferenceError: React is not defined取埗したす。

独立した゚クスポヌト汎甚モゞュヌルをモックするには
デフォルトの゚クスポヌトの䞀郚である個々の関数をすべおファむルから゚クスポヌトしたす。

䟋
dataDao.js

関数getData
関数setData
関数deleteData
゚クスポヌト{getData、setData、deleteData}

これで、デフォルトの名前付けで、ファむルからjestテストにすべおの関数をむンポヌトできたす。

dataDao.spec.js

import * as dataDao from '../ dataDao';
//むンポヌト時に割り圓おられたデフォルト名を参照するモゞュヌルをスパむしたす
jest.spyOndataDao、 'getData'
jest.spyOndataDao、 'setData'
jest.spyOndataDao、 'deleteData'

@vchinthakunta 、動䜜する可胜性がありたすが、゚クスポヌト/むンポヌト構文の䞻な目的に違反しおいるようです。他のモゞュヌルは、を介しお特定のメ゜ッドたたはデヌタフィヌルドをむンポヌトできなくなりたす。

import { justThisThing } from 'someModule';

私はそこに䜕かが欠けおいたすか

React.lazy動䜜する@MajorBreakfast 

const mockLazy = jest.fn();

jest.mock('React', () => ({
    ...jest.requireActual('React'),
    lazy: mockLazy
}));

私はただReferenceError: React is not defined取埗したす。

「React」はむンポヌトを参照しおいるので、ここでは小文字にする必芁があるず思いたすか

jest.mock('react'...)

私はここで芋た他の゜リュヌションよりも簡単な以䞋を䜿甚しおコヌドを動䜜させたした。 requireたり、 default゚クスポヌトを蚭定したりする必芁はありたせん。

helpers / Navigation.js

export const initHeader = () => {
    // initialise header
    ...
}

...

export const anotherHelperFunction = () => {
    // do stuff
    ...
}

Navigation.jsを䜿甚するコンポヌネント

import { initHeader } from '../helpers/navigation';

jest.mock('../helpers/navigation');

...

describe('Test component', () => {

    it('should reinitialise header', () => {
        const mockHeaderInit = jest.fn();
        initHeader.mockImplementation(mockHeaderInit);

        const component = mountComponent(mockProps);
        component.simulate('click');

        expect(mockHeaderInit).toBeCalled();
    }
}
mockGet = jest.fn()
jest.mock('my-module', () => ({
  ...jest.requireActual('my-module'),
  get: mockGet
}))
ReferenceError: mockGet is not defined

       4 | const mockGet = jest.fn();
       5 | jest.mock('./browserStorage', () => ({
       6 |   ...jest.requireActual('./browserStorage'),
    >  7 |   get: mockGet,
         |        ^
       8 | }));

jest.mockが持ち䞊げられおいる堎合は、 doMockか、

jest.mock('./browserStorage', () => ({
  ...jest.requireActual('./browserStorage'),
  get: jest.fn(),
}));

const {get: mockGet} = require('./browserStorage');

これはよくある問題のようです。 jestのドキュメントにこれに぀いお䜕かありたすか

それで、同じモゞュヌル内の関数をモックするための解決策はあり

次の方法でうたくいきたした。トリックは、テストの最埌にモックされた関数をリセットするこずです。
この䟋のモックは、jsonwebtokenモゞュヌルの関数を怜蚌したす。

  test('perform my test', async () => {
    // save the real jwt.verify function
    const verify = jwt.verify
    // mock it.
    jwt.verify = jest.fn().mockReturnValue({ sub: 0 })
    // do the test
    ...
    // set the real function back.
    jwt.verify = verify
  })

次の方法でうたくいきたした。トリックは、テストの最埌にモックされた関数をリセットするこずです。
この䟋のモックは、jsonwebtokenモゞュヌルの関数を怜蚌したす。

  test('perform my test', async () => {
    // save the real jwt.verify function
    const verify = jwt.verify
    // mock it.
    jwt.verify = jest.fn().mockReturnValue({ sub: 0 })
    // do the test
    ...
    // set the real function back.
    jwt.verify = verify
  })

const verifyどこで䜿甚しおいたすか ずにかく、これはモックされた関数が゚クスポヌトされたconst関数でない堎合にのみ機胜したす

それで、_同じモゞュヌル内で_関数をモックするための解決策はありたすか

倚くの怜玢を行った埌、この問題の解決策は、関数ずモックが参照できる単䞀のオブゞェクトに゚クスポヌトを保存するこずです。 以䞋の蚘事はすべお同じコンセンサスに達したした。

https://github.com/facebook/jest/issues/936#issuecomment -438975674
https://medium.com/@qjli/how -to-mock-specific-module-function-in-jest-715e39a391f4
https://luetkemj.github.io/170421/mocking-modules-in-jest

コヌドで実行可胜であれば、これらすべおの問題を完党に排陀し、目的のコヌドのテストを非垞に簡単にする別の゜リュヌションに぀いお誰も蚀及しおいないのは驚きです。

_モックしたい単䞀の関数を独自のモゞュヌルに移動したす。_

真剣に。 モゞュヌルの内郚を他の内郚ずは別にテストする必芁があるようにモゞュヌルが䜜成されおいる堎合、ほが確実に、クラスは単䞀責任の原則に違反しおいたすはい、実際のクラスではありたせんが、モゞュヌルはクラスのように機胜しおいたす。モゞュヌルはコヌドのナニットコンテナです。 その吞盀を分割し、ブヌム、あなたは必芁なものをあざけるこずができたす。

モックされた関数が䞀連のプラむベヌト状態に䟝存しおいる堎合でも、これはモゞュヌルを䜕らかの方法で分割しない理由にはなりたせん。 それが倚くの内郚状態に䟝存しおいるずいう事実は、私には、モゞュヌルの懞念が明確に考えられおいないこずを意味したす。 おそらく、分割する3番目のモゞュヌルもありたす。これは、匕数ずしお枡すこずができる、ある皮のデヌタクラスたたはDTOを衚したす。

たた、テストのためだけにプラむベヌトな関数を゚クスポヌトしおいたすか 倖郚コヌドがモックされた関数を盎接呌び出すだけでなく、それ自䜓が呌び出す必芁のある他の関数も呌び出すのはなぜですか ここで䜕らかの切断が起こっおいるに違いありたせん。 たぶん、モックされた関数はそのたたにしおおく必芁がありたすが、すべおの関数を半分に分割し、半分を削陀しお別のモゞュヌルに入れる必芁がありたす。 あなたはその考えを理解したす。

テストが非垞に困難になるず、ほずんどの堎合、リファクタリングが必芁な兆候です...

テストの䞍正行為は必芁ありたせん

const tomfoolery = require('tomfoolery'); // no longer required

このスレッドを読み、提案された゜リュヌションをテストした埌でも、これを機胜させるこずはできたせん。 私が読んだこずから、䜕人かの人々がこの䜜品を䜜りたしたが、私はどのように理解するこずができたせん。

テストに合栌するために次の䟋に远加する必芁があるコヌドを誰かに教えおもらえたすか

// a.js
export const foo = () => 'foo-' + bar()
export const bar = () => 'bar'
// a.test.js
import {
  foo,
  bar
} from './a'

describe('foo', () => {
  it('should return foo-MOCKED_BAR', () => {
    expect(foo()).toBe('foo-MOCKED_BAR')
  })

  it('should have the mocked implementation of bar', () => {
    expect(bar()).toBe('MOCKED_BAR')
  })
})

describe('bar', () => {
  it('should have the original implementation of bar', () => {
    expect(bar()).toBe('bar')
  })
})

describe('foo and bar together', () => {
  it('should have the original implementation of both', () => {
    expect(foo()).toBe('foo-bar')
  })
})

ありがずう

lodash.randomのような単䞀のlodashメ゜ッドのみをモックしたかったので、次の方法で簡単に実行できたした。

module.js

const lodash = require('lodash');

module.exports = function() {
  return lodash.random();
}

test.js

const lodash = require('lodash');
const module = require('./module.js);

it('mocks lodash', () => {
    jest.spyOn(lodash, 'random').mockImplementationOnce(() => {
      return 2;
    });

    expect(module()).toEqual(2)
});

お圹に立おば幞いです:)

typescriptを䜿甚するチヌムで機胜したのは、関数を盎接゚クスポヌトするのではなく、゚クスポヌトするconstを䜜成するこず
動䜜しない
export function doSomething(a, b) {}
働く
export const doSomething = function (a, b) {}

@arbielskのように゚クスポヌトを倉曎したした、動䜜したす しかし、2皮類の゚クスポヌトの違いは䜕ですか...

@dgrcode䟋の解決策を芋぀けたこずがありたすか 私の知る限り、あなたがやろうずしおいるこずは、Jestを介したモックではサポヌトされおいたせん。 具䜓的には、モックむンは基本的にむンポヌトを再配線しお、モゞュヌルの倖郚ビュヌにモックされたメ゜ッドが衚瀺されるようにするこずfooずbarが同じモゞュヌル内にあるため、 fooのbarのビュヌをモックアりトするこずはできたせん。

私はあなたの遞択肢が次のいずれかであるず信じおいたす
1 fooがbarを含むモゞュヌルをむンポヌトするように、コヌドを再線成したす
2 babel-plugin-rewireを䜿甚する

誀解しおいる堎合は蚂正しおください

少し異なる芁件がありたした。1぀の関数を陀いおモゞュヌル党䜓をモックしたかったのです。 @MajorBreakfastの゜リュヌションを出発点ずしお䜿甚しお、私は次のこずを思い぀きたした。

jest.mock('my-module', () => ({
  ...jest.genMockFromModule('my-module'),
  myFunction: jest.requireActual('my-module').myFunction
}))

@dgrcode䟋の解決策を芋぀けたこずがありたすか 私の知る限り、あなたがやろうずしおいるこずは、Jestを介したモックではサポヌトされおいたせん。 具䜓的には、モックむンは基本的にむンポヌトを再配線しお、モゞュヌルの倖郚ビュヌにモックされたメ゜ッドが衚瀺されるようにするこずだず思いたす。 ただし、この䟋では、 fooずbarが同じモゞュヌル内にあるため、 fooのbarのビュヌをモックアりトするこずはできたせん。

私はあなたの遞択肢が次のいずれかであるず信じおいたす

  1. fooがbarを含むモゞュヌルをむンポヌトするように、コヌドを再線成したす
  2. babel-plugin-rewireを䜿甚する

誀解しおいる堎合は蚂正しおください

それは実際に私の堎合でした
モゞュヌルをモックする方法に぀いおの私の理解はすべお台無しになりたした🀊‍♂

基本的
2぀の関数が同じモゞュヌル内にあり、盞互に呌び出す堎合

fooがbar呌び出しおいる堎合

function bar() {
  return 'some-result'
}

function foo(){
  return bar()  // <-- the function I want to mock 
}

barを新しいファむルに入れたすモックされたす

barメ゜ッドを新しいファむルに移動したした。これで、䞊蚘の䟋の倚くを䜿甚できるようになりたした。
@ yoni-abtechに感謝したす🀣

このスレッド党䜓を読んで䜕床もテストした埌の私が芋る方法には、3぀のオプションがありたす。

オプション1- constを䜿甚しおすべおの関数を宣蚀したす

これには、宣蚀よりも関数匏の䜿甚を矩務付ける必芁がありたす。 幞いなこずに、 func-style eslintルヌルがあなたを取り戻したした。

export const䜿甚するず、 _same_モゞュヌル内から他の関数​​によっお䜿甚されるspyOn関数を䜿甚できたす。

// hello.js
export const message = () => {
  return 'Hello world';
}

export const foo = () => {
  return message();
}
// hello.test.js
import * as testModule from './hello.js';

describe('test spyon with function expressions', function () {
  afterAll(() => {
    jest.restoreAllMocks();
  });
  it('should NOT mock message in foo', function () {
    const actual = testModule.foo();

    expect(actual).toBe('Hello world');
  });

  it('should mock message in foo', function () {
    jest.spyOn(testModule, 'message').mockReturnValue('my message');

    const actual = testModule.foo();

    expect(actual).toBe('my message');
    expect(testModule.message).toHaveBeenCalledTimes(1);
  });
});

オプション2- rewire babelプラグむンを䜿甚する

関数匏の䜿甚を矩務付けたくない堎合぀たり、 const 、これは良いアプロヌチかもしれたせん。

これにより、同じモゞュヌルから関数を_再配線_ 別名モックするこずができたす。 コヌドは以䞋のように芋えるず想像できたしたが、テストしおいたせん。 たた、圌らのドキュメントから、モゞュヌルから゚クスポヌトされおいない同じモゞュヌル内の関数を再配線できるようです👍、 message関数を゚クスポヌトせずに以䞋の䟋を想像しおください。

䟋

// hello.js
export function message() {
  return 'Hello world';
}

export function foo() {
  return message();
}
// hello.test.js
import * as testModule from './hello.js';

describe('test rewire api', function() {
  it('should NOT mock message in foo', function () {
    const actual = testModule.foo();

    expect(actual).toBe('Hello world');
  });

  it('should mock message in foo', function () {
    testModule.__RewireAPI__.__Rewire__('message', jest.fn().mockReturnValue('my message'));

    const actual = testModule.foo();

    expect(actual).toBe('my message');
    expect(testModule.message).toHaveBeenCalledTimes(1);
    testModule.__RewireAPI__.__ResetDependency__('message');
  });
});

䟋に぀いおは、ドキュメントを参照しおください。

泚バベルの転写が必芁です

オプション3-すべおの機胜を別々のモゞュヌル/ファむルに分割する

このオプションは最も奜たしくありたせんが、通垞のmock機胜で問題なく機胜するこずは明らかです。


PSこのトレッドは非垞に啓発的で、しばしば面癜いものでしたが、この抂芁が他の人がスレッド党䜓を読む必芁性を軜枛するこずを願っおいたす。 ✌

@nickofthymeに感謝し

@nickofthymeあなたのoption 1は私のアプリずcreate react app䞡方で倱敗したす

 FAIL  src/hello.test.js
  test spyon with function expressions
    ✓ should NOT mock message in foo (3ms)
    ✕ should mock message in foo (6ms)

  ● test spyon with function expressions › should mock message in foo

    expect(received).toBe(expected) // Object.is equality

    Expected: "my message"
    Received: "Hello world"

      17 |     const actual = testModule.foo();
      18 |
    > 19 |     expect(actual).toBe("my message");
         |                    ^
      20 |     expect(testModule.message).toHaveBeenCalledTimes(1);
      21 |   });
      22 | });

      at Object.toBe (src/hello.test.js:19:20)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 passed, 2 total
Snapshots:   0 total
Time:        1.848s
Ran all test suites related to changed files.

@danielhusarあなたは正しいようです。 申し蚳ありたせんが、これをCRAでテストする必芁がありたした。

オプション1で説明したモックをここで機胜させyarn test:helloスクリプトを䜿甚しおテストしたす。

結果

> yarn test:hello
yarn run v1.16.0
$ jest --config=jest.config.js -t=hello --verbose
 PASS  src/hello/hello.test.ts
  test hello
    ✓ should NOT mock message in foo (3ms)
    ✓ should mock message in foo (1ms)

Test Suites: 1 skipped, 1 passed, 1 of 2 total
Tests:       1 skipped, 2 passed, 3 total
Snapshots:   0 total
Time:        1.392s
Ran all test suites with tests matching "hello".
✹  Done in 2.36s.

ts-jestを䜿甚しおカスタムjest.config.jsファむルを䜿甚し、 react-scripts介さずに、 jest --config=./jest.config.js盎接呌び出す必芁がありたす。 react-scriptsでjestがどのように構成されおいるかはわかりたせんが、䜕らかの方法で構成を曎新する方法があるず思いたす。

この修正により、 *.css *.svgファむルずApp.tsx゚ラヌは無芖しおください。

それを機胜させるために行う必芁がある特別なこずはありたすか
私はかなり暙準的なセットアップtsなしを持っおいお、そのたたでは機胜しないず思いたす。

今倜はもう少し芋お、それが可胜かどうかを確認したす。

@danielhusar昚倜調べた䜿える゜リュヌションを埗るこずができたせんでした。 重芁なのは、CRAがpackage.json#jestオヌバヌラむドできるjest構成transformer package.json#jestです。 JSずTSファむルを䜿甚しおtranspiledいるbabel-jestが、 react-scriptsブロック䜿甚しおからあなたを.babelrc蚭定ファむルをし、蚭定をtest ENV圌らがどのセットreact-scripts testここ。

もっず深く掘り䞋げられたらいいのに、今は時間がない。

うヌん、私はただそれを機胜させるのに少し苊劎しおいたす私のカスタムセットアップでは、craではありたせん。
jestずbabel-jestの䞡方の最新バヌゞョン

これは私の冗談の蚭定です

module.exports = {
  name: 'my-app',
  testURL: 'http://localhost/',
  setupFiles: ['<rootDir>/setup-jest.js'],
  setupFilesAfterEnv: ['<rootDir>/setup-test.js'],
  testMatch: ['**/__tests__/**/*.test.js?(x)', '**/?(*.)+(spec|test).js?(x)'],
  testEnvironment: 'jest-environment-jsdom-fifteen',
  snapshotSerializers: ['enzyme-to-json/serializer'],
  globals: {
    ENV: 'test',
  },
  transform: {
    '^.+\\.[t|j]sx?$': 'babel-jest',
  },
};

そしお私のbabelrc

{
  "presets": [
    "@babel/react",
    ["@babel/env", {
      "corejs": "3",
      "useBuiltIns": "entry",
      "loose": true,
      "exclude": [
        "es.string.split"
      ]
    }],
    "@babel/flow"
  ],
  "plugins": [
    "array-includes",
    "lodash",
    "@babel/plugin-syntax-dynamic-import",
    "@babel/plugin-syntax-class-properties",
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-proposal-object-rest-spread",
    "@babel/plugin-proposal-optional-chaining"
  ],
  "env": {
    "test": {
      "plugins": ["dynamic-import-node"]
    }
  }
}

オプション1で苊劎しおいる人にずっおは、 () => (expression)関数の代わりに() => { return expression }を䜿甚するこずが重芁です。

オプション1を次のように倉曎するこずで、機胜するようになりたした。

import * as test from './test';

export const message = () => {
    return 'Hello world';
  }

  export const foo = () => {
    return test.message();
  }

きれいではありたせんが、動䜜するはずです。

@nickofthyme 、オプション1はあなたが持っおいるので正しいです。 ただし、コヌドを次のように倉曎するず、次のようになりたす。

const foo = () => {}
export { foo }

それからそれは壊れたす。 おそらく、新しいオブゞェクトリテラルを䜜成し、それを゚クスポヌトするためです。

興味深い芳察。 ありがずう@maletor

Jestのドキュメントには、モゞュヌルを郚分的にモックする方法の非垞に単玔で明確な䟋がありたす。 これは、ESimportステヌトメントずNoderequireステヌトメントの䞡方で機胜したす。
https://jestjs.io/docs/en/jest-object#jestrequireactualmodulename

@johncmunsonそれは良い点です。 ただし、モゞュヌルのモックを瀺したこの䟋は、 jest.mock _once_を実行する必芁があるだけで、モックされたメ゜ッドのいずれもそのモゞュヌルからの別の゚クスポヌトを䜿甚しない堎合にのみ機胜したす。

䞊蚘の䟋を芋おください... fooずbar間でモゞュヌルを異なる方法でモックする方法を瀺すために、 barを远加したした。

export const message = (): string => {
  return 'Hello world';
}

export const foo = (): string => {
  return message();
}

export const bar = (): (() => string) => {
  return foo;
}

jest.mockをjest.requireActualず䞀緒に䜿甚するず、次のようになるず思いたす。

import * as mockTestModule from './hello';

jest.mock('./hello');
const actualTestModule = jest.requireActual('./hello');

describe('test hello', function () {
  afterAll(() => {
    jest.restoreAllMocks();
  });

  // first test doesn't depend on any other method of the module so no mocks
  it('should NOT mock message in foo', function () {
    const actual = actualTestModule.foo();

    expect(actual).toBe('Hello world');
  });

  // the second I want to mock message in foo
  it('should mock message in foo', function () {
    jest.spyOn(mockTestModule, 'message').mockReturnValue('my message');
    const actual = actualTestModule.foo();

    expect(actual).toBe('my message'); // fails
    expect(mockTestModule.message).toHaveBeenCalledTimes(1); // never called
  });

  it('should mock foo in bar', function () {
    jest.spyOn(mockTestModule, 'foo').mockReturnValue('my message');
    const actual = actualTestModule.bar();

    expect(actual()).toBe('my message'); // fails
    expect(mockTestModule.message).toHaveBeenCalledTimes(1); // never called
  });
});

jest.doMock別々にモックしおみおも、同じ結果が埗られたした。


クリックしおコヌドを衚瀺

`` `ts
import * as testModule from './ hello';

describe 'test hello'、function{
afterAll=> {
jest.restoreAllMocks;
};

it('should NOT mock message in foo', function () {
  const actual = testModule.foo();

  expect(actual).toBe('Hello world');
});

it('should mock message in foo', function () {
  jest.doMock('./hello', () => {
    // Require the original module to not be mocked...
    const originalModule = jest.requireActual('./hello');

    return {
      ...originalModule,
      message: jest.fn().mockReturnValue('my message'),
    };
  });
  const actual = testModule.foo();

  expect(actual).toBe('my message'); // fails
  expect(testModule.message).toHaveBeenCalledTimes(1); // never called
});

it('should mock foo in bar', function () {
  jest.doMock('./hello', () => {
    // Require the original module to not be mocked...
    const originalModule = jest.requireActual('./hello');

    return {
      ...originalModule,
      foo: jest.fn().mockReturnValue('my message'),
    };
  });
  const actual = testModule.bar()();

  expect(actual).toBe('my message'); // fails
  expect(testModule.foo).toHaveBeenCalledTimes(1); // never called
});

};
`` `

このアプロヌチの問題は、実際のモゞュヌルを芁求し、次にfooを呌び出すず、モックではなく実際のmessage関数を呌び出すこずです。

私はそれがこれほど単玔であるこずを望みたすが、私が芋るずころ、これはこのスレッドの䟋には圹立ちたせん。 ここで䜕かが足りない堎合はお知らせください。 私は喜んで過ちを認めたす。

解決策を探しおいるこれに出くわした人にずっお、1぀のファむルに倚くのconst /関数を゚クスポヌトし、私がテストしおいるファむルにそれらをむンポヌトするずき、以䞋は私のために働いおいるようです

function mockFunctions() {
  const original = require.requireActual('../myModule');
  return {
    ...original, //Pass down all the exported objects
    test: jest.fn(() => {console.log('I didnt call the original')}),
    someFnIWantToCurry: {console.log('I will curry the original') return jest.fn((...args) => original.someFnIWantToCurry(...args)}),
  }
jest.mock('../myModule', () => mockFunctions());
const storage = require.requireMock('../myModule');
`

以䞋は機胜し、少し短いです

const module = require('./module');
jest.spyOn(module, 'myFn').mockImplementation(() => 'val');

掻字䜓で、ちょうどimportの代わりにrequire 

import * as module from './module';

これには、元の機胜を簡単に埩元し、モックをクリアできるずいう利点がありたす。

解決策を探しおいるこれに出くわした人にずっお、1぀のファむルに倚くのconst /関数を゚クスポヌトし、私がテストしおいるファむルにそれらをむンポヌトするずき、以䞋は私のために働いおいるようです

function mockFunctions() {
  const original = require.requireActual('../myModule');
  return {
    ...original, //Pass down all the exported objects
    test: jest.fn(() => {console.log('I didnt call the original')}),
    someFnIWantToCurry: {console.log('I will curry the original') return jest.fn((...args) => original.someFnIWantToCurry(...args)}),
  }
jest.mock('../myModule', () => mockFunctions());
const storage = require.requireMock('../myModule');
`

以䞋は機胜し、少し短いです

const module = require('./module');
jest.spyOn(module, 'myFn').mockImplementation(() => 'val');

掻字䜓で、ちょうどimportの代わりにrequire 

import * as module from './module';

これには、元の機胜を簡単に埩元し、モックをクリアできるずいう利点がありたす。

そうです、オブゞェクトにgetterしか定矩されおいない堎合も、このメ゜ッドは機胜したせん。 ゚ラヌメッセヌゞは次のようになりたす。

Test suite failed to run

    TypeError: Cannot set property useContent of #<Object> which has only a getter

この堎合、おそらくjest.mock(..)を䜿甚する必芁がありたす。 bowing_man

私のモックは以䞋を䜿甚しお動䜜しおいたす。

import { unsubscribe } from "../lib/my-lib"
import { MyComponent } from "./index"

test("unsubscribe gets called", () => {
    const module = require("../lib/my-lib")
    jest.spyOn(
        module,
        "unsubscribe"
    ).mockImplementation(() => jest.fn())

    const { getByTestId } = render(() => <MyComponent  />)

    let button = getByTestId("trigger.some.action.button")

    fireEvent.press(button)

    expect(unsubscribe).toHaveBeenCalled()
})

それほど゚レガントに芋えず、簡単に拡匵できないので、非垞にうたく機胜し、今のずころ私の堎合に適しおいたす。しかし、誰かが他の玠晎らしい構文を提案できるなら これは、機胜しおいるように芋える唯䞀の構文です。

es6モゞュヌルコヌド

export const funcA = () => {};
export const funcB = () => {
  funcA();
};

CommonJSにトランスパむルした埌

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.funcB = exports.funcA = void 0;

var funcA = function funcA() {};

exports.funcA = funcA; // You can mock or add a spy  on this `funcA`

var funcB = function funcB() {
  funcA();  // This is still original `funcA`
};

exports.funcB = funcB;

この状況を解決する方法はたくさんありたす。

  1. モック/スパむされたfuncA䜿甚できるように、このようにコヌドを倉曎する必芁がありたす
function funcA() {}
exports.funcA = funcA;

function funcB() {
  exports.funcA(); // Now, this `exports.funcA` is added a spy or mocked. Keep the same reference to `funcA`
}
exports.funcB = funcB;

たたは、

export let funcA = () => {};
export const funcB = () => {
  exports.funcA();
};

ナニットテストの結果

 PASS  myModule.test.ts (9.225s)
  funcB
    ✓ should call funcA (3ms)

-------------|---------|----------|---------|---------|-------------------
File         | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------|---------|----------|---------|---------|-------------------
All files    |     100 |      100 |     100 |     100 |                   
 myModule.ts |     100 |      100 |     100 |     100 |                   
-------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        10.967s
  1. rewireパッケヌゞを䜿甚しおfuncAをモックしたす
    ..。

さらに、次のドキュメントを確認する必芁がありたす https  requireが正確に䜕をするかを確認する

このstackoverflowの投皿の解決策は私のために働いた
https://stackoverflow.com/a/53402206/1217998

基本的に最初に、倉換したいすべおの関数をjest.fnに倉換したす

jest.mock('../../utils', () => {
  const actualUtils = jest.requireActual('../../utils');
  const originalImplementation = actualUtils.someFun;

  return {
    ...actualUtils,
    someFun: jest.fn()
      .mockImplementation(originalImplementation),
  };
});
const utils = require('../../utils');

その埌、必芁に応じお通垞のように䜿甚したり、このようにモックしたりできたす

jest.spyOn(utils, 'someFun').mockReturnValueOnce(true);

これを䜿甚しお、元の実装を取埗できたす

beforeEach(() => {
    jest.clearAllMocks();
  });

このstackoverflowの投皿の解決策は私のために働いた
https://stackoverflow.com/a/53402206/1217998

基本的に最初に、倉換したいすべおの関数をjest.fnに倉換したす

jest.mock('../../utils', () => {
  const actualUtils = jest.requireActual('../../utils');
  const originalImplementation = actualUtils.someFun;

  return {
    ...actualUtils,
    someFun: jest.fn()
      .mockImplementation(originalImplementation),
  };
});
const utils = require('../../utils');

その埌、必芁に応じお通垞のように䜿甚したり、このようにモックしたりできたす

jest.spyOn(utils, 'someFun').mockReturnValueOnce(true);

これを䜿甚しお、元の実装を取埗できたす

beforeEach(() => {
    jest.clearAllMocks();
  });

ありがずうございたした

Jestのドキュメントには、モゞュヌルを郚分的にモックする方法の非垞に単玔で明確な䟋がありたす。 これは、ESimportステヌトメントずNoderequireステヌトメントの䞡方で機胜したす。
https://jestjs.io/docs/en/jest-object#jestrequireactualmodulename

モゞュヌル内からモック関数を呌び出した堎合は動䜜したせん。

たた、元の関数を倉曎せずに、いく぀かのカスタム远加倉数を䜿甚しお関数を呌び出す方法で関数をモックするこずが圹立぀堎合があるこずもわかりたした。

jest.mock('./someModule', () => {
  const moduleMock = require.requireActual('./someModule');
  return {
    ...moduleMock,
    // will mock this function 
    someFunction: (args) =>
      moduleMock.someFunction({
        ...args,
        customArgument,
      }),
  };
});

私の堎合、関数にcome configを枡す必芁がありたした。これがないず、デフォルトのものが䜿甚されたす。

これが私がこれを行うために芋぀けた唯䞀の方法なので、あなたがより良いたたはより簡単なアむデアを思い぀いた堎合は、聞いお喜んでいたす:)

FWIW https://github.com/magicmark/jest-how-do-i-mock-x/blob/master/src/function-in-same-module/READMEで、実行可胜な䟋を䜿甚しおさたざたなアプロヌチをたずめたした

これはOPの質問/問題には答えたせんが、リファクタリングを䌎う解決策です。 関数を異なるファむルに分割し、それらのむンポヌトをモックするのが最も簡単な方法であるこずがわかりたした。

// package.json
...
"scripts": {
    "test": "jest",

...
"devDependencies": {
    "@babel/preset-env": "^7.11.5",
    "jest": "^24.9.0",
...

`` `js
// babel.config.js

module.exports = {
プリセット[
[
'@ babel / preset-env'、
{{
タヌゲット{
ノヌド '珟圚'、
}、
}、
]、
]、
};

```js
// module-utils.js

export const isBabaYaga = () => {
  return false
}

// module.js

import { isBabaYaga } from './module-utils'

export const isJohnWickBabaYaga = () => {
  return isBabaYaga()
}
// modules.test.js

import { isJohnWickBabaYaga } from './module';

jest.mock('./module-utils', () => ({
    isBabaYaga: jest.fn(() => true)
}))

test('John Wick is the Baba Yaga', () => {

    // when
    const isBabaYaga = isJohnWickBabaYaga()

    // then
    expect(isBabaYaga).toBeTruthy()
});
PASS  src/module.test.js
✓ John Wick is the Baba Yaga (4ms)

最近、この問題が発生したした。 コヌドを倉曎できないため、提案された゜リュヌションはどれも機胜したせん。 babel-plugin-rewireも私には機胜したせん。 関数が同じモゞュヌル内の別の関数によっお呌び出されたこずをテストするための他の解決策はありたすか これは正盎に蚀うず、うたくいくか、これを行うbabelプラグむンがあるはずです。 どんな助けでも倧歓迎です

最近、この問題が発生したした。 コヌドを倉曎できないため、提案された゜リュヌションはどれも機胜したせん。 babel-plugin-rewireも私には機胜したせん。 関数が同じモゞュヌル内の別の関数によっお呌び出されたこずをテストするための他の解決策はありたすか これは正盎に蚀うず、うたくいくか、これを行うbabelプラグむンがあるはずです。 どんな助けでも倧歓迎です

https://github.com/facebook/jest/issues/936#issuecomment -659597840をチェックアりトしたしたか そこには、モック関数が同じファむルで呌び出す最小限の再珟がありたす。

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡