最近、ReactコンポーネントのcomponentDidMount
メソッドで、あるカスタムメソッドが条件付きで呼ばれることをテストしたいと思いました。
componentDidMount() {
if (this.props.initOpen) {
this.methodName();
}
}
私はテストフレームワークとしてJestを使用しており、モック/スパイのための jest.fn()
が含まれています。 以下のようにすれば、Sinonでもかなり簡単にテストできると読みました。
sinon.spy(Component.prototype, "methodName");
const wrapper = mount(<Component {...props} />);
expect(wrapper.instance().methodName).toHaveBeenCalled();
これをJestで以下のように再現しようとしています。
Component.prototype.methodName = jest.fn();
const wrapper = mount(<Component {...props} />);
expect(wrapper.instance().methodName).toHaveBeenCalled();
このコードは失敗し、以下のようなエラーが発生します。
jest.fn() value must be a mock function or spy.
Received:
function: [Function bound mockConstructor]
この機能をJestでテストすることは可能でしょうか?もし可能ならば、どのようにして?
鍵となるのはjestsのspyOn
メソッドを使うことです。以下のようになるはずです。
const spy = jest.spyOn(Component.prototype, 'methodName');
const wrapper = mount(<Component {...props} />);
wrapper.instance().methodName();
expect(spy).toHaveBeenCalled();
ここにあるように 例:https://stackoverflow.com/questions/40393486/test-if-function-is-called-react-and-enzyme
注意 テストを実行するたびに、スパイされた関数をクリアすることも最善の方法です。
let spy
afterEach(() => {
spy.mockClear()
})
https://facebook.github.io/jest/docs/en/jest-object.html#jestclearallmocks
遅くなりましたが、これを見て、componentDidMount
がネストされたメソッドへの呼び出しを開始することをテストするためには、次のようなテストを行うことを提案します。
Module (モジュール)
componentDidMount() {
if (this.props.initOpen) {
this.methodName();
}
}
テスト - 良好
it('should call methodName during componentDidMount', () => {
const methodNameFake = jest.spyOn(MyComponent.prototype, 'methodName');
const wrapper = mount(<MyComponent {...props} />);
expect(methodNameFake).toHaveBeenCalledTimes(1);
});
componentDidMountを呼び出した場合、
methodNameが
componentDidMount`を介して呼び出されたというアサーションがより有効になります。
テスト - 悪い。
it('should call methodName during componentDidMount', () => {
const spy = jest.spyOn(Component.prototype, 'methodName');
const wrapper = mount(<Component {...props} />);
wrapper.instance().methodName();
expect(spy).toHaveBeenCalled();
}
このようにテストを書くことで、メソッドを呼び出し、それが呼び出されたことをアサートします。もちろん、メソッドを呼び出しただけなので、呼び出されたことになります。