web-dev-qa-db-ja.com

ユニットテストの方法ReactコンポーネントshouldComponentUpdateメソッド

React shouldComponentUpdate メソッドを実装するコンポーネントがあり、それを単体テストしたいと思います。理想的には、ユニット内のコンポーネントの小道具または状態を変更できます再レンダリングするかどうかをテストして確認します。役立つ場合は enzyme を使用しています。

21
Liron Yahdav

おそらくshouldComponentUpdateを直接呼び出すだけです。

何かのようなもの

const comp = shallow(<Comp {...props} />)
const shouldUpdate = comp.instance().shouldComponentUpdate(nextProps, nextState)
expect(shouldUpdate).toBe(true/false)

コンポーネントが実際にレンダリングされたか、レンダリングされなかったかどうかを判断してテストしようとすると、おそらくそれ以上の問題が発生します。酵素を使ってそれをどのように行うかさえわかりません。レンダリングされた出力が以前と同じでない限り、shouldComponentUpdateからfalseを返さない可能性があるため、レンダリングされた出力から実際に抜け出すことはできません。そのため、レンダリングが発生したかどうかを判断することは、出力だけからはできませんでした。

それを直接呼び出すことによるテストは私にとっても問題ないようです。 ReactがshouldComponentUpdateの戻り値を正しく使用する限り(そうしないと、より大きな問題が発生します)信頼できる限り、安全です。

36
TLadd

結果がわかっている場合は、おそらくshouldComponentUpdateを独立した関数としてテストしたくないでしょう。

ドキュメント で述べたように、setPropsまたはsetStateを使用できます。これはおそらく-少なくとも私にとって-コンポーネントから正確な結果を期待するためのより良いアプローチです関連する値を更新するとき。

あなたのMyComponent.test.js

import { expect } from 'chai';
import sinon from 'sinon-sandbox';
import { shallow } from 'enzyme';

it('updates when changing state or props', () => {
  const wrapper = shallow(<MyComponent />);

  const shouldComponentUpdate = sinon.spy(MyComponent.prototype, 'shouldComponentUpdate');

  expect(shouldComponentUpdate).to.have.property('callCount', 0);

  wrapper.setProps({ propThatWillUpdateTheComp: 'foo' });

  // or in case you are testing component update in case of state change
  // wrapper.setState({ stateThatWillUpdateTheComp: 'bar' });

  expect(shouldComponentUpdate).to.have.property('callCount', 1);

  expect(shouldComponentUpdate.returned(true)).to.be.equal(true);

});
3
Jalal