Edited at

enzymeでReactのテストをしてみた

More than 3 years have passed since last update.


enzymeとは

airbnbが開発したReactのテストを行うためのライブラリです。

https://github.com/airbnb/enzyme

なんとこのライブラリ、Reactのドキュメントに 「airbnbの作ったやつがあってこっちの方が簡単だよ」 的なことが書いてあるんですよ(冒頭のNoteの部分)

=> Test Utilities

特徴は react-addons-test-utils 等を使わずに簡潔に shallow renderassert が出来るといったところです。

shallow render はテスト対象のcomponentのみを実際に走らせてrenderし、

入れ子になっているcomponentについてはmockを代わりにrenderする仕組みのようです。

assertについてはjQueryのようなセレクタを使ってReactのcomponentツリーを検索出来るところが特徴です。

Installation のセクションを読めばすぐに導入できます。


試してみた

jestと併用して試してみました。

import React from "react"; // 直接使わないけどこれがないとエラーしました

import { shallow } from "enzyme";
jest.unmock("../components/hoge");
import Hoge from "../components/hoge";
import Foo from "../components/foo";

describe("Hoge", () => {
it("render foo", () => {
const wrapper = shallow(<Hoge />); // ShallowWrapperというオブジェクトが返る
// findするとここでもShallowWrapperが返り、Fooが存在する数がlengthに入っている
expect(wrapper.find(Foo).length).toBe(1);
// jquery的なクラス名の検索も出来る
expect(wrapper.find(".bar").length).toBe(1);
});
});

findに失敗してもとにかく ShallowWrapper が返り、lengthで存在確認をするのはjQuery感がありますね。

たまにcomponentクラスをfindに渡しても検索に失敗することがあったので、文字列で "Foo" などと渡してみると成功しました。

この成功時と失敗時の実装の違いはまだ特定できていません。

// これがうまくいかないときは

expect(wrapper.find(Foo).length).toBe(1);
// これで通った
expect(wrapper.find("Foo").length).toBe(1);

ただ、いちいちテスト対象ではないFooをimportするのもめんどいし、全部文字列検索でいいかなと思いました。


Shallow WrapperオブジェクトのAPI

色々あるので便利に使えそうです

https://github.com/airbnb/enzyme/blob/master/docs/api/shallow.md


まとめ

facebookの用意したテストライブラリより簡潔に書けて、assertも簡単に出来るのでおすすめです。

しばらくはこれを使おうと思います。


追記

2016-11-01 react-addons-test-utils をテストファイルでimportしていなかったので devDependencies からも削除したところテスト実行時にエラーしてしまいました。enzymeが内部で使っているので devDependencies に入れておく必要があるみたいです。