Я пытался тестировать контейнеры Relay, как компоненты в приложении Flux. В частности, я хочу убедиться, что они отображают правильный контент для данного состояния и свойств и что они вызывают методы для изменения данных в соответствующих местах; в Flux это призыв к создателю действия, в Relay - это призыв к Relay.Store.update
или this.props.relay.setVariables
.
Моей первой попыткой было построить RelayTestUtil
объект с помощью renderContainerIntoDocument
метода. Я во многом основывал его на https://github.com/facebook/relay/blob /master/src/tools/< sizesmocks sizes/RelayTestUtils.js, https://github.com/facebook/relay/blob/master/src/legacy/store/ и Relay Контейнерные тесты. При этом использовалось минимальное количество имитаций, и он отлично подходил для тестирования рендеринга контейнера, но был совершенно бесполезен для тестирования изменений данных. Попытки слежки за звонками в 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();
});
person
agrauch
schedule
02.10.2015