中继:预计会收到一个对象,其中传播了`...MyComponent_user`,但未找到片段引用`
Posted
技术标签:
【中文标题】中继:预计会收到一个对象,其中传播了`...MyComponent_user`,但未找到片段引用`【英文标题】:Relay: Expected to receive an object where `...MyComponent_user` was spread, but the fragment reference was not found` 【发布时间】:2021-05-12 07:46:55 【问题描述】:我有一个使用 useFragment 钩子的组件,我试图弄清楚如何传入数据并使用 @testing-library/react 对其进行测试:
// @flow
import graphql, useFragment from 'react-relay/hooks';
import Field from '../../common/fields/Field.react';
import type MyComponent_user from './__generated__/MyComponent_user.graphql';
type Props =
user: MyComponent_user,
;
export default ( user: userFragment : Props) =>
const user = useFragment(
graphql`
fragment MyComponent_user on UserType
id
fullName
userType
details
user
id
address
city
state
zipCode
country
phone
title
company
`,
userFragment,
);
const userDetails = user?.details;
const userHref = '/user?userId=';
return (
<div className="user-container">
user?.fullName && <Field label="Full Name" value=user.fullName />
user?.userType && (
<Field
label="User Type"
value=user.userType === '1' ? 'Employee' : 'User'
/>
)
userDetails?.address && <Field label="Address" value=userDetails.address />
userDetails?.city && <Field label="City" value=userDetails.city />
userDetails?.state && <Field label="State" value=userDetails.state />
userDetails?.zipCode && <Field label="Zipcode" value=userDetails.zipCode />
userDetails?.country && <Field label="Country" value=userDetails.country />
userDetails?.phone && <Field label="Phone" value=userDetails.phone />
userDetails?.title && <Field label="Title" value=userDetails.title />
userDetails?.company && <Field label="Company" value=userDetails.company />
</div>
);
;
我正在尝试编写测试:
import render, screen from '@testing-library/react';
import RelayEnvironmentProvider from 'react-relay/hooks';
import RelayEnvironment from '../../../../environment';
import MyComponent from '../MyComponent.react';
const props =
user:
id: 1,
fullName: 'Meek Mill',
userType: '0',
details:
address: '294 Oak Street',
city: 'Philadelphia',
state: 'PA',
zipCode: '19019',
country: 'US',
phone: '555-555-5555',
title: 'Owner',
company: 'Dream Chasers Records',
user:
id: '237895024906790',
,
,
,
;
describe('when the user type is 0', () =>
it('displays User as the User Type', () =>
render(
<RelayEnvironmentProvider environment=RelayEnvironment>
<MyComponent ...props />
</RelayEnvironmentProvider>,
);
screen.debug();
);
);
我收到此错误:
Invariant Violation: Relay: Expected to receive an object where `... MyComponent_user` was spread, but the fragment reference was not found`. This is most likely the result of:
- Forgetting to spread ` MyComponent_user` in `useFragment()`'s parent's fragment.
- Conditionally fetching ` MyComponent_user` but unconditionally passing a fragment reference prop to `useFragment()`. If the parent fragment only fetches the fragment conditionally - with e.g. `@include`, `@skip`, or inside a `... on SomeType ` spread - then the fragment reference will not exist. In this case, pass `null` if the conditions for evaluating the fragment are not met (e.g. if the `@include(if)` value is false.)
12 | console.log('userFragment:', userFragment);
13 | console.log('props:', props);
> 14 | const user = useFragment(
| ^
15 | graphql`
16 | fragment MyComponent_user on UserType
17 | id
如果在文档中添加一些测试示例会很棒。
【问题讨论】:
【参考方案1】:在测试 Relay 框架时,您需要了解几件事。
我们需要在中继测试中使用两个主要模块: createMockEnvironment: 它提供中继环境接口和模拟层,允许resolving
、reject
和模拟操作query、mutation和订阅。
mockPayloadGenerator:允许您为需要测试的组件生成和维护一组模拟数据。
根据您希望在测试中涵盖的测试用例数量,您需要提供一组不同的模拟数据并将其传递给MockPayloadGenerator
。
import render, cleanup from '@testing-library/react';
import MockPayloadGenerator from 'relay-test-utils';
const DEFAULT_PROPS =
user:
id: 1,
fullName: 'Meek Mill',
userType: '0',
details:
address: '294 Oak Street',
city: 'Philadelphia',
state: 'PA',
zipCode: '19019',
country: 'US',
phone: '555-555-5555',
title: 'Owner',
company: 'Dream Chasers Records',
user:
id: '237895024906790',
,
,
,
;
function TestRenderer(): React.Node
const node = useLazyLoadQuery<MyTopLevelComponentTestQuery>(
graphql`
query MyTopLevelComponentTestQuery
@relay_test_operation
node(id: "TEST_FAKE_USER_ID")
...MyComponent_user
`,
,
);
return user != null && <MyComponent user=node />;
describe('MyComponent', () =>
let environment = createMockEnvironment();
function renderWithEnvironment(node: React.Node): React.Node
return (
<RelayEnvironmentProvider environment=environment>
<Suspense fallback=null>node</Suspense>
</RelayEnvironmentProvider>,
);
function mockNextOperation(props): void
// if you use `resolveMostRecentOperation` you don't need to
// have MyTopLevelComponentTestQuery
// environment.mock.resolveMostRecentOperation(operation =>
environment.mock.queueOperationResolver(operation =>
MockPayloadGenerator.generate(operation,
UserType()
return
node:
...props,
,
;
,
),
);
beforeEach(() =>
environment = createMockEnvironment();
cleanup();
);
it('when the user type is 0', () =>
mockNextOperation(DEFAULT_PROPS);
const getByText = render(
renderWithEnvironment(<TestRenderer />),
);
// whatever your logic is to test your component
expect(getByText('User Type: User')).toBeTruthy();
);
it('when the user type is 1', () =>
mockNextOperation(ANOTHER_TEST_PROPS);
const getByText = render(
renderWithEnvironment(<TestRenderer />),
);
// whatever your logic is to test your component
expect(getByText('User Type: Employee')).toBeTruthy();
);
);
【讨论】:
以上是关于中继:预计会收到一个对象,其中传播了`...MyComponent_user`,但未找到片段引用`的主要内容,如果未能解决你的问题,请参考以下文章
React.Children.only 预计会收到单个 React 元素子错误
当 2 个模型在 flask-sqlalchemy 中继承相同的对象时收到警告
我收到一个错误“传播类型只能从对象 types.ts(2698) 创建”
我收到“错误:React.Children.only 预计会收到一个 React 元素子项。”带有 TouchableWithoutFeedback