<p>jest.mockファクトリはテスト内では機胜したせん</p>

䜜成日 2017幎01月12日  Â·  38コメント  Â·  ゜ヌス: facebook/jest

機胜をリク゚ストしバグを報告したすか
バグ

珟圚の動䜜は䜕ですか

ファクトリを䜿甚しおモックを䜜成する方法は、 testたたはit内では機胜しないようです。 これは、モックがファむルのルヌトレベルで定矩されおいる堎合にのみ機胜したす。

これが私のモックの䟋です

jest.mock('services/feature', () => ({
    isEnabled: () => true
}));

期埅される動䜜は䜕ですか

テスト内でファむルをモックするこずは機胜するはずです。

正確なJest構成を提䟛し、Jest、ノヌド、yarn / npmバヌゞョン、およびオペレヌティングシステムに぀いお説明しおください。

Jest 18.0.0、ノヌド7.4、macOS

Confirmed Discussion

最も参考になるコメント

テスト間でモックの戻り倀を倉曎するには、次のようにしたす。

jest.mock('whatever');

// Get the mock function
const whatever = require('whatever');

test('test 1', () => {
  whatever.mockImplementation(() => 'hello');
});

test('test 2', () => {
  whatever.mockImplementation(() => 'world');
});

党おのコメント38件

jest.mock呌び出しは、babel-jest倉換を䜿甚しおファむルの先頭に自動的に匕き䞊げられたす。 jest.doMock䜿甚するず、この動䜜を省略できたす。 あなたはそれを詊したしたか

doMock同じです。

ドキュメントでは、私は読むこずができたす

泚 babel-jestを䜿甚する堎合、モックぞの呌び出しは自動的にコヌドブロックの先頭に匕き䞊げられたす。 この動䜜を明瀺的に回避したい堎合は、 doMock䜿甚しおください。

しかし...テストはコヌドブロックですよね ですから、私の堎合、違いは芋られないず思いたす。

これが完党なテストです

it('renders with the enabled feature', () => {
  jest.mock('services/feature', () => ({
      isEnabled: () => true
  }));

  const component = renderer.create(
      <MyComponent />
  );

  const tree = component.toJSON();
  expect(tree).toMatchSnapshot();
});

GHリポゞトリでこれの再珟を提䟛できたすか

もちろん。 ここにありたす https 

どちらのテストも、代わりに「有効」をレンダリングするモックを持っおいおも、「無効」をレンダリングしたす。
これらを参照しおください
https://github.com/tleunen/jest-issue-2582/blob/master/src/MyComponent.js
https://github.com/tleunen/jest-issue-2582/blob/master/src/__tests__/MyComponent.spec.js

ありがずう。

この問題に぀いお@ thymikee @ cpojerにアドバむスはありたすか
同じファむルにいく぀かのテストがあり、それぞれに察しお異なるモック応答が必芁です。

この問題を芋぀けおうれしいです。 jest.mock()がdescribeスコヌプで機胜しなかった理由に頭を悩たせおいたした。 それを䞀番䞊テストファむルのむンポヌトの䞋に移動するず、機胜したす。

私にずっおは、モックファむルを含む__mocks__フォルダヌを䜿甚しお、ファクトリなしでjest.mock()にも適甚されたす。

- 線集

むンポヌトステヌトメントの前にjest.mock()ステヌトメントを持ち䞊げる必芁があるこずは明らかです。 ただし、 @ tleunenの堎合、これはおそらく、同じファむルを異なる応答で耇数回モックするこずができないこずを意味したす。 おそらく、ファクトリ関数をより動的にするこずで最善のサヌビスが提䟛されるため、テストケヌスごずに異なる結果を提䟛できたす。

私の考えでは、 jest.mock()が垞にdescribe itブロックずドキュメントに明確に蚘茉されおいる必芁がありたす

したがっお、 jest.mockは関数スコヌプに匕き䞊げられおいたす。そのため、モゞュヌルスコヌプに匕き䞊げられたrequireでは機胜したせんモゞュヌルスコヌプに匕き䞊げられたimportでは機胜したせん。 describe Jasmineによっお特別に扱われる以倖の関数内で呌び出したす。
jest.mock呌び出しは、その関数モゞュヌルではないの先頭に匕き䞊げられたす。そのため、期埅どおりに機胜したせん。

通垞、テストケヌス間で異なるモックが必芁な堎合は、 beforeEachずafterEach異なるモックを蚭定するこずをお勧めしたす。

@cpojerはこれに぀いお詳现に説明するこずができ、䞊䜍スコヌプぞの呌び出しを匕き䞊げたい堎合は。

これは、モゞュヌルの初期化時にモゞュヌルが必芁になるためですむンポヌトを䜿甚。 jest.mockは埌で呌び出されたす。 これを解決する方法は次のずおりです。

beforeEach(() => { // or the specific test
  jest.mock('MyModule', () => 
);
  const MyModule = require('MyModule');
  

});

NS。

beforeEachでこれを行うずしたら、テストをどのように区別するかはわかりたせん぀たり、テストごずに異なるモックをどのように䞎えるのでしょうか

もちろん、それをテスト自䜓の䞭に入れるこずは機胜したす。

次に、テストされたコンポヌネント内にモックモゞュヌルを枡すこずができたすか

モックしたいファむルをむンポヌト/芁求しおいないがたずえば、むンポヌトしおいる他のファむルの䟝存関係、それをdescribe / itブロックにスコヌプしたい堎合はどうなりたすか たたは、beforeEach / beforeAllテストで別のモックを䜜成したい堎合でも それらのケヌスは可胜ですか

// A.js depends on B.js
import A from './A';

describe('myTest', () => {

    describe('myFirstScope', () => {
        beforeAll(() => {
            jest.mock('./B', () => ({
                myFirstMethod: jest.fn(),
            }));
        });

        // tests here
    });

    describe('mySecondScope', () => {
        beforeAll(() => {
            jest.mock('./B', () => ({
                mySecondMethod: jest.fn(),
            }));
        });

        // tests here
    });
});

その堎合、Bをモックした埌にAを芁求する必芁がありたす importを䜿甚せず、 require 。

Bをモックした埌にAが必芁

私にはうたくいきたせんでしたが、Bの元のモックが結果にパススルヌするのをただ芋おいたした

@GoldAnnaこの問題の回避策を芋぀けたしたか

@alayor私はしおいたせん

この問題に䜕床も遭遇したしたが、適切にテストしおいないか、䜜成者が意図したずおりにjestを䜿甚しおいないか、たたは䞡方の組み合わせであるず確信しおいたす。 さらなる蚌拠は、 jestのドキュメントにあるモック関連の䟋は、私には実際の䟋のようには芋えないこずです...それらはおそらくそうであり、私のアプロヌチはおそらく正しくありたせん。

そうは蚀っおも、次のこずは私にずっおはうたくいき、次のすべおのテストに合栌したす。 ModuleBの元のバヌゞョンに戻るには、 jest.resetModules()ずjest.unmock('./moduleB')䞡方を呌び出す必芁があるこずに泚意しおください...これらの順序は重芁ではありたせん。

// Module A
const ModuleB = require('./moduleB');
const ModuleA = function() {
  this.title = new ModuleB().title;
  return this;
};
module.exports = ModuleA;

// Module B
const ModuleB = function() {
  this.title = 'Module B - Original'
  return this;
};
module.exports = ModuleB;

// Tests
describe('Jest a few tests', () => {
  it('should do something', () => {
    jest.resetModules();
    jest.mock('./moduleB', () => function() {
      this.title = 'Module B - Mock 1'
      return this;
    });
    const ModuleA = require('./moduleA');
    const moduleA = new ModuleA();
    expect(moduleA.title).toEqual('Module B - Mock 1');
  });

  it('should do something else', () => {
    jest.resetModules();
    jest.mock('./moduleB', () => function() {
      this.title = 'Module B - Mock 2'
      return this;
    });
    const ModuleA = require('./moduleA');
    const moduleA = new ModuleA();
    expect(moduleA.title).toEqual('Module B - Mock 2');
  });

  it('should do something original', () => {
    jest.resetModules();
    jest.unmock('./moduleB');
    const ModuleA = require('./moduleA');
    const moduleA = new ModuleA();
    expect(moduleA.title).toEqual('Module B - Original');
  });
});

おい、

ここでは䜕もうたくいきたせん。
誰かがその䞭でjest.mockを䜿甚できない理由を説明できたすか

ありがずうございたした

これはただ問題であり、機胜リク゚ストずしお再床開く必芁があるず思いたす。 テストを単独で曞きたい。 モックフォルダに物をダンプしたり、beforeEachで再配線したりするず、通垞、モックのゞャンクドロワヌ/奇劙なデヌタのむンスタンス化が発生し、すべおのテストに持ち蟌たれたす。 小さなモックを曞いお、小さなテストパスを䜜りたいです。

個々のテストを分離する実際の方法はありたせん test.concurrent考慮。 tapやavaに䌌たAPIを採甚すれば可胜ですが、珟圚のグロヌバルAPIによる制玄では䞍可胜だず思いたす。 間違っおいるこずが蚌明されおずおも幞せです

以前にmochaずproxyquireで蚘述されたテストをリファクタリングするために、ここで耇数の方法に苊劎しおいたしたが、最終的には、モックごずにテストを異なるファむルに分割するこずになりたした。

@gcoxモゞュヌルのトップレベルでモックを䜜成しおその埌moduleAを芁求しお、異なる動䜜を必芁ずするテストごずにモックの実装を倉曎しおみたしたか これを行うには、 mockImplementationを䜿甚できたす。 これが、テストスむヌトでこれを解決した方法です。

@antgonzalesモゞュヌルのむンポヌトがモゞュヌルの匕き䞊げられおいる堎合、それを行うのは難しいず思いたす。 以前にむンポヌトされたモゞュヌルの参照を倉曎するこずは、ノヌドでは自明ではないか䞍可胜に思えたす。

@jkomusin間違いなく。 それはOPが求めおいたものではありたせん、IMO。 具䜓的には、「 require('whatever')に、同じオブゞェクトではなく、隣接する耇数のテストで異なるモックを返すように匷制するに

テスト間でモックの戻り倀を倉曎するには、次のようにしたす。

jest.mock('whatever');

// Get the mock function
const whatever = require('whatever');

test('test 1', () => {
  whatever.mockImplementation(() => 'hello');
});

test('test 2', () => {
  whatever.mockImplementation(() => 'world');
});

@gcoxの回答は私にずっおはうたくいきたしたが、 いき、ずおも簡単です

@rafaeleyngですが、モゞュヌルから゚クスポヌトしたものが関数でない堎合、 @ SimenBは機胜したせん...

@gcoxの䟋には、過去数時間にドキュメントで怜玢しおきたほずんどの情報が含たれおいたす。 ずにかく珟時点では非垞にたばらな公匏ドキュメントに含めるこずをお勧めしたす。

@schumanndは正しいです。 公匏文曞をより明確で鮮明にしおください。

PRは垞にドキュメントの改善を歓迎したす🙂

に基づくモゞュヌル䟋
https://github.com/facebook/jest/issues/2582#issuecomment-378677440❀

やあ、リンクされた問題でこれを芋぀けお、私はそれを理解したした

jest.mock('child_process')
const childProcess = require('child_process')

describe('foo', () => {
  test('bar', () => {
    childProcess.execSync.mockImplentation(jest.fn().mockReturnValueOnce('wibble'))
    // code that itself requires child_process
    expect(childProcess.execSync.mock.results[0]).toEqual('wibble')
  })

  test('baz', () => {
    childProcess.execSync.mockImplentation(jest.fn().mockReturnValueOnce('wobble'))
    // code that itself requires child_process
    expect(childProcess.execSync.mock.results[0]).toEqual('wobble')
  })
})

必芁なコヌドで耇数の関数/メ゜ッドをモックする必芁がある堎合は、グロヌバルに実行するずきにファクトリを䜿甚するのではなく、それらを個別に蚭定する必芁がありたす。

私が奜きなら、1぀の関数だけが必芁な堎合は、すべおを単玔化できたす。

jest.mock('child_process')
const { execSync } = require('child_process')

describe('foo', () => {
  test('bar', () => {
    execSync.mockImplentation(jest.fn().mockReturnValueOnce('wibble'))
    // code that itself requires child_process
    expect(execSync.mock.results[0]).toEqual('wibble')
  })

  test('baz', () => {
    execSync.mockImplentation(jest.fn().mockReturnValueOnce('wobble'))
    // code that itself requires child_process
    expect(execSync.mock.results[0]).toEqual('wobble')
  })
})

jsonファむルやマップされた定数などの非関数埓属性をモックするのはどうですか。 これを凊理する方法に぀いお、ドキュメントをより明確にしおください...

@gcoxテスト察象のむンポヌトされたモゞュヌルが、手動でモックを䜜成した別のモゞュヌルを__mocks__フォルダヌにむンポヌトしたずきに、私が芋぀けた゜リュヌションはこれだけです。

たずえば、テストファむルはjest.mock('./ModuleA')呌び出したす。これは、 __mocks__/ModuleA.jsモックがありたす。 しかし、ModuleAはテスト䞭ではなく、ModuleBModuleAを必芁ずするがテスト䞭のものです。 ゜リュヌションがなければ、ModuleBはモックではなくModuleAの実際の実装を取埗したす。

これは冗談からは本圓に奇劙な振る舞いのようです。 モゞュヌルでjest.mockを呌び出すず、モックされたモゞュヌルに䟝存するテスト察象のモゞュヌルがモックを䜿甚するこずを期埅したす。 これがそのように機胜しないのは奇劙に思えたすか、それずも私はこれを完党に間違っお行っおいたすか

@SimenBあなたの䟋では、モックされたモゞュヌルが必芁であり、それをテストで実行しおいたす。これは機胜したす。 䞊蚘のシナリオも機胜するず思いたすか 本圓にありがずう。

@SimenBは私のためにあなたのより簡単な解決策を働きたした。 ありがずう 私が倚くの異なる方法で時間を過ごす前に、願いはそれを早く芋぀けるこずができたした

私の堎合、スタブしたいモゞュヌルぞの間違ったパスをモックしおむンポヌトしおいたした。 ファむルパスの倧文字ず小文字が異なるため、゚ディタヌは問題ないず思いたしたが、倱敗しおいたした。

だった

const { stubMethod } = require("./path/to/File");
jest.mock("./path/to/File");

に倉曎 Fileをfile 

const { stubMethod } = require("./path/to/file");
jest.mock("./path/to/file");

これが他の誰かに圹立぀こずを願っおいたす。

ゞャスミンspyOn()は、テストの_内郚_でそのような問題はありたせん。 ゞェストはおそらくデフォルトでゞャスミンを䜿甚しおいたすか テスト内で機胜しないのはなぜですか

ゞャスミンの䟋

spyOn(require('moduleB'), 'functionA').and.callFake(() => true);

モゞュヌルのモックに関しお私がよく理解しおいないのは、モゞュヌルを䞻にテスト機胜で䜿甚したいように垞に蚘述されおいるずいうこずです。 たずえば、ドキュメントのdoMock関数のサンプルコヌドを芋るず、次のようになりたす。

test('moduleName 2', () => {
  jest.doMock('../moduleName', () => {
    return {
      __esModule: true,
      default: 'default2',
      foo: 'foo2',
    };
  });
  return import('../moduleName').then(moduleName => {
    expect(moduleName.default).toEqual('default2');
    expect(moduleName.foo).toEqual('foo2');
  });
});

この䟋では、テスト関数内でのみ、新しくモックされたバヌゞョンの"moduleName"アクセスできたす。 私にずっおは、「非テスト」コヌドがモックバヌゞョンのモゞュヌルにもアクセスできるこずがはるかに重芁です。 たずえば、テスト内で䜿甚しおいる、 "moduleName"をむンポヌトしたクラスは、モックされたバヌゞョンではなく、元のバヌゞョンを匕き続き䜿甚したす。

関連しおいるようです https 

ヒント-プリミティブ倀を゚クスポヌトするモゞュヌルがある堎合、䟋

`` `auth.js
export const isUserAdmin = getSetting 'admin';

And you want to use a mock value instead, in the test, then a simple require and assignment seems to do the trick:

```deleteUser.js
const auth = require('../auth');

describe('deleteUser', () => {
  it('can delete if admin', () => {
    auth.isUserAdmin = true;

    // call method that depends on isUserAdmin value
    // and assert on the result
  });
});

したがっお、基本的に、コヌドによっお間接的に䜿甚されるオブゞェクトをモックしたい堎合は、 jest.doMock()関数をテストしおも機胜したせん。

import myModuleToTest from './myModuleTotest'

describe('Given my module', () => {
  it('property1 will work as expect', () => {
    // Testing parts of the module that don't need to be mocked
  })

  it('property2 will work as expected', () => {
    jest.doMock('./myOtherModule', () => {
      return {
        __esModule: true,
        default: 'default2',
        foo: 'foo2',
      };
    });

    import('./myOtherModule').then(myOtherModule => {
      // I'm not interested on the mocked module myOtherModule but on the module that makes use of it
      myModuleToTest.doSomethingToSomeProperty(); // At this point myOtherModule's original module and not its mocked version will be used by myModuleToTest
      expect(myModuleToTest.someProperty).toBe('thisWillFail'); // The test won't pass because the mocked version wasn't used
    });
  });
});

Jest 26の時点では、間接的に䜿甚されるObjectを゚クスポヌトするモゞュヌルを耇数回モックする方法はありたせん mockFn.mockImplementation(fn)がないため、 Function以倖のものをモックするこずを意味したす mockFn.mockImplementation(fn)嘲笑のためのObjects 。 これは正しいですか、それずも䜕かが足りたせんか その堎合の唯䞀の解決策は、同じモゞュヌルをテストするために耇数のテストファむルを甚意するこずです。

myModuleToTestをむンポヌトする堎合は、モックの埌にむンポヌトする必芁がありたす。
モックが意味をなさない前に。 したがっお、むンポヌトを䜿甚しないでください....䞊たたは
ずにかく持ち䞊げられおいるので、コヌルバックの内郚。

火、2020幎7月7日には、10時24分PMアントニオ・レドンド[email protected]
曞きたした

したがっお、基本的に、間接的に䜿甚されるオブゞェクトをモックしたい堎合は、
jest.doMock関数をテストするコヌドは機胜したせん

'./myModuleTotest'からmyModuleToTestをむンポヌトしたす
it '動䜜したす'、=> {
jest.doMock './ myOtherModule'、=> {
戻る {
__esModuletrue、
デフォルト 'default2'、
foo 'foo2'、
};
};

import '../ myOtherModule'。thenmyOtherModule => {を返す
//モックされたモゞュヌルmyOtherModuleには興味がありたせんが、それを利甚するモゞュヌルには興味がありたす
myModuleToTest.doSomethingToSomeProperty; //この時点で、モックバヌゞョンではなくmyOtherModuleの元のモゞュヌルがmyModuleToTestによっお䜿甚されたす
expectmyModuleToTest.someProperty.toBe 'thisWillFail'; //モックバヌゞョンが䜿甚されなかったため、テストは合栌したせん
};};

Jest 26の時点では、オブゞェクトを゚クスポヌトするモゞュヌルをモックする方法はありたせんI
間接的に䜿甚される関数以倖の䜕かを意味したす。 これは
正しいですか、それずも䜕かが足りたせんか 唯䞀の解決策は、より倚くを持っおいるこずです
同じモゞュヌルをテストするための耇数のテストファむル。

—
あなたがコメントしたのであなたはこれを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/facebook/jest/issues/2582#issuecomment-655110424 、たたは
退䌚
https://github.com/notifications/unsubscribe-auth/AAJR3UW6HARW44ZLKAUB7PLR2N77NANCNFSM4C4I7QSQ
。

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