Flux アプリケーションのコンポーネントと同じように、Relay コンテナーをテストしようとしています。具体的には、特定の状態と小道具に対して正しいコンテンツをレンダリングし、適切な場所でデータを変更するメソッドを呼び出すことを確認したいと考えています。Flux では、これはアクション作成者への呼び出しであり、Relay では、Relay.Store.update
またはへの呼び出しthis.props.relay.setVariables
です。
私の最初の試みはRelayTestUtil
、メソッドを使用してオブジェクトを構築することでしたrenderContainerIntoDocument
。https://github.com/facebook/relay/blob/master/src/tools/ mocks /RelayTestUtils.js、https://github.com/facebook/relay/blob/master/src/legacyに大きく基づいています/store/ mocks /GraphQLStoreQueryResolver.js、および Relay Container テスト。これは非常に最小限のモックを使用し、コンテナー レンダリングのテストには最適でしたが、データ変更のテストにはまったく役に立ちませんでした。Relay.Store.update
andの呼び出しをスパイしようとしthis.props.relay.setVariables
たり、データの変更をモックしたりすることは、価値がある以上に面倒になりました。
__mocks__\react-relay.js
Relay を完全にモック化するために追加し、より単純なバージョンのRelayTestUtils.renderContainerIntoDocument
を使用して Relay プロパティをコンテナーに注入することにしました。私はこの解決策に完全に満足しているわけではありませんが、今のところうまくいっているようです。
__mocks__\react-relay.js
:
var Relay = require.requireActual('react-relay');
var React = require('react');
module.exports = {
QL: Relay.QL,
Mutation: Relay.Mutation,
Route: Relay.Route,
Store: {
update: jest.genMockFn()
},
createContainer: (component, containerSpec) => {
const fragments = containerSpec.fragments || {};
// mock the static container methods
Object.assign(component, { getFragment: (fragmentName) => fragments[fragmentName] });
return component;
}
};
RelayTestUtils.js
:
const React = require('react');
const ReactDOM = require('react-dom');
const RelayTestUtils = {
renderContainerIntoDocument(containerElement, relayOptions) {
relayOptions = relayOptions || {};
const relaySpec = {
forceFetch: jest.genMockFn(),
getPendingTransactions: jest.genMockFn().mockImplementation(() => relayOptions.pendingTransactions),
hasOptimisticUpdate: jest.genMockFn().mockImplementation(() => relayOptions.hasOptimisticUpdate),
route: relayOptions.route || { name: 'MockRoute', path: '/mock' },
setVariables: jest.genMockFn(),
variables: relayOptions.variables || {}
};
return ReactDOM.render(
React.cloneElement(containerElement, { relay: relaySpec }),
document.createElement('div')
);
}
};
export default RelayTestUtils;
テストは次のようになりますfragmentData
。GraphQL レスポンスの形状と一致します。
it('changes items', () => {
const myContainer = RelayTestUtils.renderContainerIntoDocument(
<MyContainer { ...fragmentData }/>,
{ variables: { itemId: 'asdf' } }
);
myContainer.changeItem();
expect(myContainer.props.relay.setVariables).toBeCalled();
});