私が取り組んでいるプロジェクトの単体テストを書いているとき、私は同じ問題を抱えていました。それを解決するための良いパターンを得たと思います。うまくいけば、それは役に立ちます:
環境
handleClick
これは、太い矢印表記を使用して定義されたメソッドを持つ React コンポーネントの例です。
import React, { Component } from 'react';
class Foo extends Component {
componentWillMount() {
this.handleClick();
}
handleClick = (evt) => {
// code to handle click event...
}
render() {
return (
<a href="#" onClick={this.handleClick}>some foo link</a>
);
}
}
問題
このリンクで説明されているように、 Babelはコードをトランスパイルして、handleClick
メソッドがインスタンス化後にのみ使用できるようにします (生成されたコンストラクター関数の31 行目から 33 行目を確認してください)。
ここでの問題は、クラスをインスタンス化する前に、太い矢印表記を使用して定義されたメソッドにアクセスする必要がある場合があることです。
たとえば、クラス メソッドの単体テストを作成していて、目的の単体テストのみをテストできるようcomponentWillMount
に をスタブ化したい場合を考えてみましょう。しかし、インスタンス化後にhandleClick
しかアクセスできず、インスタンス化ライフサイクルの一部としてメソッドが自動的に呼び出されるため、問題があります。handleClick
componentWillMount
React
解決
このような問題を解決するために簡単なパターンを適用する方法は次のとおりです。
import React from 'react';
import { mount } from 'enzyme';
import { expect } from 'chai';
import sinon from 'sinon';
import Foo from './foo';
describe('Foo', () => {
describe('componentWillMount method', () => {
const handleClickStub = sinon.stub();
class FooWrapper extends Foo {
constructor(props) {
super(props);
this.handleClick = handleClickStub;
}
}
it('should register a click event listener to the externalElement property', () => {
handleClickStub.reset();
mount(<FooWrapper />);
expect(handleClickStub.calledOnce).to.be.true;
});
});
});
説明
Foo
元のコンポーネントを初期化した後、元のコンポーネントをコンストラクターのwhere にラップしました。元のメソッドをスタブ バージョンFooWrapper
に置き換えて、クラスのプロパティ テストを行います。handleClick
componentWillMount