I am testing a component with React testing library and Jest.
The component:
import { useMutation, useFragment } from 'react-relay';
import PropTypes from 'prop-types';
import { useState } from 'react';
const fragment = graphql`
fragment UserForm_user on User {
id
firstName
lastName
role
}
`;
const mutation = graphql`
mutation UserFormMutation($input: UpdateUserInput!) {
updateUser(input: $input) {
user {
id
databaseId
role
firstName
lastName
}
errors {
field
messages
}
}
}
`;
Component.displayName = 'UserForm';
export default function Component(props) {
const data = useFragment(fragment, props.user);
const [commit, isInFlight] = useMutation(mutation);
const [errors, setErrors] = useState([]);
const [user, setUser] = useState(data);
const onChange = ({ target: { name, value } }) => {
setUser((user) => ({ ...user, [name]: value }));
};
const onBlur = () => {
commit({
variables: {
input: {
id: user.id,
...user,
},
},
onCompleted: ({ updateUser: { errors } }) => {
if (errors.length > 0) {
setErrors(errors);
}
},
});
};
return (
<>
<Table.Col>
<Form.Group>
<Form.Input
id="firstName"
name="firstName"
errors={errors}
onChange={onChange}
onBlur={onBlur}
value={user.firstName}
/>
</Form.Group>
</Table.Col>
<Table.Col>
<Form.Group>
<Form.Input
id="lastName"
name="lastName"
errors={errors}
onChange={onChange}
onBlur={onBlur}
value={user.lastName}
/>
</Form.Group>
</Table.Col>
<Table.Col></Table.Col>
<Table.Col></Table.Col>
<Table.Col>
<Form.Group>
<Form.Select id="role" name="role" errors={errors} onChange={onChange} onBlur={onBlur} value={user.role}>
<option value="admin">Admin</option>
<option value="consultant">Consultant</option>
</Form.Select>
</Form.Group>
</Table.Col>
</>
);
}
Component.propTypes = {
The test :
import { describe, expect, it } from 'vitest';
import { act, render, screen } from '@testing-library/react';
import { RelayEnvironmentProvider } from 'react-relay/hooks';
import { MockPayloadGenerator, createMockEnvironment } from 'relay-test-utils';
import userEvent from '@testing-library/user-event';
import Component from '../../src/components/UserForm';
describe('UserForm', () => {
it('submit the form fields', async () => {
const environment = createMockEnvironment();
environment.mock.queueOperationResolver((operation) => {
return MockPayloadGenerator.generate(operation, {
User() {
return {
id: 'user-1',
firstName: 'Chris',
lastName: 'Koo',
role: 'admin',
};
},
});
});
const user = {
id: 'user-1',
firstName: 'Chris',
lastName: 'Koo',
role: 'admin',
};
render(
<RelayEnvironmentProvider environment={environment}>
<Component user={user} />
</RelayEnvironmentProvider>,
);
await userEvent.type(screen.getByLabelText('Voornaam'), 'Chris');
await userEvent.type(screen.getByLabelText('Achternaam'), 'Koo');
await userEvent.type(screen.getByLabelText('Gebruiker type'), 'admin');
await userEvent.click(screen.getByRole('button', { name: 'Opslaan' }));
const mutationOperation = environment.mock.getMostRecentOperation();
expect(mutationOperation.request.variables.input).toEqual({
id: 'user-1',
firstName: 'Chris',
lastName: 'Koo',
role: 'admin',
});
act(() => {
environment.mock.resolveMostRecentOperation((operation) =>
MockPayloadGenerator.generate(operation, {
UpdateUser() {
return {
user: {
id: 'user-1',
databaseId: 1,
firstName: 'Chris',
lastName: 'Koo',
role: 'admin',
},
errors: [],
};
},
}),
);
});
});
});
I am getting this error :
Invariant Violation: Relay: Expected to receive an object where ...UserForm_user
was spread, but the fragment reference was not found`. This is most likely the result of:
- Forgetting to spread
UserForm_user
inuseFragment()
's parent's fragment. - Conditionally fetching
UserForm_user
but unconditionally passing a fragment reference prop touseFragment()
. 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, passnull
if the conditions for evaluating the fragment are not met (e.g. if the@include(if)
value is false.)
can you help with it?