gpt4 book ai didi

reactjs - Relay + React 的测试策略

转载 作者:行者123 更新时间:2023-12-03 13:07:37 27 4
gpt4 key购买 nike

这些天我正在尝试 React + Relay + Graphql。不幸的是,我找不到任何简单方便的方法来测试 Relay Container 包装的 React 组件。

基本上,我希望通过 TDD 实现这些目标,

  1. 渲染容器并测试其内容,
  2. 更改变量并测试其对内容的更改。

与 React + Flux 相比,React + Relay 更像是黑盒,或者说,声明式。

我可以看到人们模拟 Relay.createContainer 来绕过 Relay 并仅仅测试 React 组件。它使继电器部分未被覆盖,并且无法通过测试驱动该部分。 https://github.com/facebook/relay/issues/161

此外,我通读了 Relay 的测试用例,渲染模拟容器确实很乏味。 https://github.com/facebook/relay/blob/master/src/tools/mocks/RelayTestUtils.js

如果您能分享您的解决方案,我将非常感激。

谢谢!

最佳答案

我一直在尝试测试 Relay 容器,就像测试 Flux 应用程序中的组件一样。具体来说,我想确保它们为给定的状态和 Prop 呈现正确的内容,并且它们调用方法来在适当的位置更改数据;在 Flux 中,这是对 Action 创建者的调用,在 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.Store.update的电话和this.props.relay.setVariables ,或者模拟数据更改,变得比其值(value)更麻烦。

我决定添加__mocks__\react-relay.js完全模拟 Relay 并使用 RelayTestUtils.renderContainerIntoDocument 的更简单版本将 Relay 属性注入(inject)到容器中。我对这个解决方案并不完全满意,但它目前似乎有效。

__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();
});

关于reactjs - Relay + React 的测试策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32760418/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com