Ho provato a testare i contenitori di inoltro come se fossero componenti in un'applicazione Flux. Nello specifico, voglio assicurarmi che visualizzino il contenuto corretto per un determinato stato e oggetti di scena e che chiamino metodi per cambiare i dati in luoghi appropriati; in Flux questa è una chiamata a un creatore di azioni, in Relay questa è una chiamata a Relay.Store.update
o this.props.relay.setVariables
.
Il mio primo tentativo è stato quello di creare un oggetto RelayTestUtil
con un metodo renderContainerIntoDocument
. L'ho basato pesantemente su 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 e sui test del contenitore di rilancio. Questo ha usato il mocking molto minimale ed era ottimo per testare il rendering dei container ma era completamente inutile per testare le modifiche dei dati. Cercando di spiare le chiamate a Relay.Store.update
e this.props.relay.setVariables
, o di imitare le modifiche ai dati, è diventato più difficile di quanto valeva.
Ho optato per l'aggiunta di __mocks__\react-relay.js
per il relè completamente simulato e utilizzando la versione più semplice di RelayTestUtils.renderContainerIntoDocument
per iniettare le proprietà di inoltro in un contenitore. Non sono completamente soddisfatto di questa soluzione, ma sembra funzionare per ora.
__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;
test simile a questa, dove fragmentData
corrisponde alla forma della risposta GraphQL:
it('changes items',() => {
const myContainer = RelayTestUtils.renderContainerIntoDocument(
<MyContainer { ...fragmentData }/>,
{ variables: { itemId: 'asdf' } }
);
myContainer.changeItem();
expect(myContainer.props.relay.setVariables).toBeCalled();
});
Penso che questa sia l'idea migliore: http://stackoverflow.com/questions/38327428/integration-testing- di relè-contenitori-con-jest-contro-un-lavoro-graphql-back –