通常ReactのコンポーネントをEnzymeを使ってテストするには以下のように記述する感じ。
import React from 'react';
import { expect } from 'chai';
import { shallow, mount } from 'enzyme';
import sinon from 'sinon';
import MyComponent from './MyComponent';
it('renders without crashing', () => {
const wrapper = mount(<MyComponent />);
expect(wrapper.find("input[type='text']").length).to.equal(0);
});
しかし、この MyComponent
が Material-UI に依存している場合はテストを実行すると以下のようなエラーが出てしまいます。
Warning: Failed context type: The context `muiTheme` is marked as required in `TextField`, but its value is `undefined`.
このエラーの意味は、MyComponent
が muiTheme
を必要としているよということなので、以下のように <MuiThemeProvider />
で囲むとエラーが出なくなります。
const wrapper = mount(<MuiThemeProvider><MyComponent /></MuiThemeProvider>);
でもこれでエラーが引っ込んだとしても、wrapper.props()
や wrapper.state()
にうまいことアクセスできなかったりするので、テストをいい感じに記述することができません。
解決策
この問題を解決するには、以下のようにテストを記述することで解決できます。
import React from 'react';
import { expect } from 'chai';
import { shallow, mount } from 'enzyme';
import sinon from 'sinon';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import PropTypes from 'prop-types';
import MyComponent from './MyComponent';
const muiTheme = getMuiTheme();
it('renders without crashing', () => {
const wrapper = mount(<MyComponent />, {
context: { muiTheme },
childContextTypes: { muiTheme: PropTypes.object },
});
expect(wrapper.find("input[type='text']").length).to.equal(0);
});
ポイントは以下の部分。
const wrapper = mount(<PasswordField id="hello" name="world" />, {
context: { muiTheme },
childContextTypes: { muiTheme: PropTypes.object },
});
あと、これに必要な以下のモジュールをロードしているところです。
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import PropTypes from 'prop-types';
const muiTheme = getMuiTheme();