我一直試圖測試中繼容器,就像我將在Flux應用程序中的組件一樣。具體來說,我想確保他們爲給定的狀態和道具提供正確的內容,並且他們調用方法在適當的位置更改數據;在Flux中,這是對動作創建者的調用,在Relay中,這是對Relay.Store.update
或this.props.relay.setVariables
的調用。
我的第一個嘗試是用renderContainerIntoDocument
方法構建一個RelayTestUtil
對象。我基於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
和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();
});
反應母語,我認爲這是最好的想法:http://stackoverflow.com/questions/38327428/integration-testing-繼電器容器 - 與 - 開 - 對 - 工作 - graphql-back –