はじめに
前回enzymeの導入について記事を書きました。
これまでは単純にrenderされるDOMのチェックしかしてなかったのですが、今回はonClickなどのハンドラをテストしてみました。
前回同様jestをベースにテストを行っています。
コンポーネント内のメソッドでハンドルしている場合
// 実装
export default class Hoge extends Component {
render() {
return (
<div>
<a href="#" onClick={this.onClickLink.bind(this)}>Click me</a>
</div>
);
}
onClickLink(e) {
e.preventDefault();
console.log("clicked!");
}
}
この場合、クリックイベントに対して正しいハンドラが呼ばれているかをテストする必要があるかと思います。
ですので Hoge.prototype.onClick()
をモックに差し替えます。
// テスト
describe("Hoge", () => {
describe("when click link", () => {
it("call Hoge.prototype.onClick() method", () => {
const wrapper = shallow(<Hoge />);
const instance = wrapper.instance(); // これでHogeクラスのインスタンスが取得できる
const fakeOnClickLink = jest.fn(); // モックを作成
instance.onClickLink = fakeOnClickLink; // モックで上書き
wrapper.find("a").simulate("click"); // これだけでclickイベントが発生する!!
expect(fakeOnClickLink).toBeCalled(); // 呼ばれている
});
});
});
SharrowWrapper.prototype.instance()
でマウントされたコンポーネントの実体を取得できるため、そのオブジェクトのハンドラをモックで上書きしてしまえばいいみたいです。
input[type="text"]等でstateの変化をテストする場合
// 実装
export default class Hoge extends Component {
constructor(props) {
super(props);
this.state = {
email: ""
};
}
render() {
const { email } = this.state;
return (
<div>
Email: <input type="email" value={email} onChange={this.onChange.bind(this)}/>
</div>
);
}
onChangeEmail(e) {
this.setState({ email: e.target.value });
}
}
inputのvalueをstateで管理している場合ですね。
この場合はハンドラが呼ばれるだけでなく、stateの更新まで行えるところまでをテストしたいところです。
ですのでテストは以下のようにしました。
// テスト
describe("Hoge", () => {
describe("when input email", () => {
it("change email state", () => {
const wrapper = shallow(<Hoge />);
const fakeEventObject = { target: { value: "sample@example.com" } };
// simulateの2番目以降がハンドラの引数に渡されます
wrapper.find("input").simulate("change", fakeEventObject);
// stateメソッドで取得したいキー名を指定すると値が返る
expect(wrapper.state("email")).toBe("sample@example.com");
});
});
});
今度はハンドラは元のままにしておいて、changeイベントが起きた時のイベントオブジェクトをfakeに差し替えました。
ShallowWrapper.prototype.state
を使い、欲しいstateのキー名を指定することで値を取得できます。
まとめ
いやーenzyme使えば使うほど馴染んできますね。とにかくなんでも簡潔に書けて素晴らしいです。