編集:解決しました!答えは下にスクロール
react-intl
コンポーネント テストでは、コンテキストにアクセスできるようにする必要があります。問題は、親ラッパーmount()
なしで (Enzyme の) 単一コンポーネントをマウントしていることです。<IntlProvider />
これは、プロバイダーをラップすることで解決されますが、 は ではなくインスタンスをroot
指します。IntlProvider
CustomComponent
The Testing with React-Intl: Enzymeドキュメントはまだ空です。
<カスタム コンポーネント />
class CustomComponent extends Component {
state = {
foo: 'bar'
}
render() {
return (
<div>
<FormattedMessage id="world.hello" defaultMessage="Hello World!" />
</div>
);
}
}
標準テストケース (望ましい) (酵素 + モカ + チャイ)
// This is how we mount components normally with Enzyme
const wrapper = mount(
<CustomComponent
params={params}
/>
);
expect( wrapper.state('foo') ).to.equal('bar');
ただし、コンポーネントはライブラリFormattedMessage
の一部として使用react-intl
するため、上記のコードを実行すると次のエラーが発生します。
Uncaught Invariant Violation: [React Intl] Could not find required `intl` object. <IntlProvider> needs to exist in the component ancestry.
で包むIntlProvider
const wrapper = mount(
<IntlProvider locale="en">
<CustomComponent
params={params}
/>
</IntlProvider>
);
これにより、必要なコンテキストが提供CustomComponent
さintl
れます。ただし、次のようなテスト アサーションを実行しようとすると、次のようになります。
expect( wrapper.state('foo') ).to.equal('bar');
次の例外が発生します。
AssertionError: expected undefined to equal ''
IntlProvider
これはもちろん、私たちの ではなくの状態を読み取ろうとするためCustomComponent
です。
アクセスの試みCustomComponent
以下を試してみましたが、役に立ちませんでした:
const wrapper = mount(
<IntlProvider locale="en">
<CustomComponent
params={params}
/>
</IntlProvider>
);
// Below cases have all individually been tried to call `.state('foo')` on:
// expect( component.state('foo') ).to.equal('bar');
const component = wrapper.childAt(0);
> Error: ReactWrapper::state() can only be called on the root
const component = wrapper.children();
> Error: ReactWrapper::state() can only be called on the root
const component = wrapper.children();
component.root = component;
> TypeError: Cannot read property 'getInstance' of null
問題は、「ルート」操作を実行しながら、コンテキストを使用してマウントするにはどうすればよいかCustomComponent
intl
CustomComponent
ということです。