web-dev-qa-db-ja.com

JestとEnzymeでReactコンポーネントライフサイクルメソッドをモックする方法は?

フルDOMレンダリングのEnzymeドキュメント ここ には、Sinonを使用したライフサイクルメソッドをスパイする次の例が含まれています。

describe('<Foo />', () => {

  it('calls componentDidMount', () => {
    sinon.spy(Foo.prototype, 'componentDidMount');
    const wrapper = mount(<Foo />);
    expect(Foo.prototype.componentDidMount.calledOnce).to.equal(true);
  });
});

Jestのモック関数を使用した場合と同等のものは何ですか?

私はCreate-React-Appを使用していますが、Jestで同じことができる場合は、Sinonを含めたくありません。

テストは次のようになります。

describe('<App />', () => {

  it('calls componentDidMount', () => {
    jest.fn(App.prototype, 'componentDidMount');
    const wrapper = mount(<App />);
    expect(App.prototype.componentDidMount.mock.calls.length).toBe(1);
  });
});

この場合、 App.prototype.componentDidMountは、Sinonの場合と同じ関数スパイを参照しません。

モック関数が実際にどのように機能するかに関するJestのドキュメントは少し制限されています。私はjest.fn()が行っていることについての議論 ここ に従いましたが、それは実際にはsinon.spy()と同等ではないようです。

Jestでそのテストを複製するにはどうすればよいですか?

8
Lewis

jest.fnには実装用のパラメーターしかないため、これはjestではこのようには機能しません。しかし、もっと重要なことは、テストしたいオブジェクトの内部をスパイしてはいけないということです。 Fooは、いくつかのプロパティを入れて、いくつかのものをレンダリングして戻すことができるブラックボックスと考える必要があります。次に、FooのようなcomponentDidMountの内部関数が呼び出されることをテストする必要がないことに気付きます。重要なのはブラックボックスの出力だけです。

しかし、本当に必要な場合は、とにかくテストしてください。

const spy = jest.fn()
const componentDidMount = Foo.prototype.componentDidMount
Foo.prototype.componentDidMount = function(){
  spy()
  componentDidMount()
}
4

Jest 19の時点で、次のことができます。

describe('<App />', () => {
  it('calls componentDidMount', () => {
    const spy = jest.spyOn(App.prototype, 'componentDidMount');
    const wrapper = mount(<App />);
    expect(spy).toHaveBeenCalled();
    spy.mockReset();
    spy.mockRestore();
  });
});

jest.spyOnモック関数 を返します。mockClearmockResetmockRestoreなどの通常使用可能なすべてのメソッドを使用します。

mountを酵素で、またはcreateをreact-test-rendererで実行する前に、スパイを設定して、作成されたインスタンスがスパイされているモック関数への参照を持つようにしてください。

3
Ryan H.