React 在测试时不会在状态更改时重新渲染



我正在测试一个react组件,该组件具有一个简单的Material-ui开关,用于更新布尔字段。当我在本地运行应用程序时,该组件没有任何问题。

在我的测试中,我通过MockedProvider模拟图形调用。模拟的提供程序按预期工作,我可以看到初始响应和更新响应到达并更新状态。然而,当我找到开关并在屏幕上检查它时,它仍然未被选中。我的测试失败了:

Received element is checked: <input checked="" class="PrivateSwitchBase-input-40 MuiSwitch-input" name="callbackEnabled" type="checkbox" value="" />

我的第一个猜测是React没有渲染这个状态变化。我需要强制渲染吗?或者测试这种行为的正确方法是什么?

测试:

it('should update boolean field', async () => {
const mocks = [
{
request: {
query: myQuery,
variables: {
clientId: 'cl_0',
},
},
result: {
data: {
myQuery: {
callbackEnabled: true
},
},
},
},
{
request: {
query: myMutation,
variables: {
clientId: 'cl_0',
callbackEnabled: false,
},
},
result: {
data: {
myMutation: {
callbackEnabled: false,
},
},
},
},
];
let base = null;

await act(async () => {
const { baseElement, } = render(
<MockedProvider mocks={mocks} addTypename={false}>
<MyComponent clientId="cl_0" error={undefined} />
</MockedProvider>
);
base = baseElement;
});
// eslint-disable-next-line no-promise-executor-return
await new Promise((resolve) => setTimeout(resolve, 0));
// check for info: https://www.apollographql.com/docs/react/development-testing/testing/#testing-the-success-state
// testing initial state: these pass
expect(base).toBeTruthy();
expect(screen.getByRole('checkbox', { name: /callbacks/i })).toBeInTheDocument();
expect(screen.getByRole('checkbox', { name: /callbacks/i })).toBeChecked();
// simulate a switch click
await act(async () => {
userEvent.click(screen.getByRole('checkbox', { name: 'Callbacks' }));
});
// eslint-disable-next-line no-promise-executor-return
await new Promise((resolve) => setTimeout(resolve, 0)); // wait for response

// fails here
expect(screen.getByRole('checkbox', { name: /callbacks/i })).not.toBeChecked();
});

首先向复选框组件添加test-id,如下所示:

<input
type="checkbox"
checked={checkboxState}
data-testid="checkboxID" />

然后在我们的测试中测试复选框状态是否改变:

const input = getByTestId("checkboxID");
// Assuming we set initial status for checkbox component to be false
expect(input.checked).toEqual(false);
fireEvent.click(input);
// check handling click in checkbox
expect(input.checked).toEqual(true);

最新更新