我有一个 useEffect 取决于 useMutation 查询的响应,该查询在单击“保存”按钮时触发
main.tsx
// This is my UseMutation, which triggers on the save button click.
const [
createSomething,
{
data: createSomethingResponse,
loading: createSomethingInProgress,
error: createSomethingError,
},
] = useMutation(CREATE_SOMETHING);
const onSaveClick = () => {
createSomething({
variables: {
input: {
name: 'some-name',
notes: 'some-notes',
items: [{some-items}]
},
},
});
};
useEffect(() => {
const something = createSomethingResponse?.createSomething;
if (stocktake) {
/* Some code part that shows the successful banner message */
closeTrowser(); // closes the trowser window
}
}, [createSomethingResponse, sandbox]);
main.test.tsx
describe ("some description",() => {
function renderComponent(compProps: CreateSomethingProps, mocks?: any) {
const component = renderWithIntl(
<MockedProvider mocks={mocks} addTypename={false}>
<CreateSomethingView {...compProps} sandbox={sandboxMock as Sandbox} />
</MockedProvider>,
);
act(() => {
jest.advanceTimersByTime(1000);
});
return component;
}
test('some test', async() => {
let props: CreateSomethingProps;
props = {
intl: mockIntlShape,
};
jest.spyOn(sandbox, 'useSandbox').mockReturnValue(sandboxMock);
const mockItems = [
{
id: '1',
name: 'Product1',
},
];
const mocks = [
{
request: {
query: CREATE_STOCKTAKE,
variables: {
input: {
name: 'test1',
notes: 'notes1',
items: mockItems,
},
},
},
result: {
createSomething: {
id: 'bab8f338-2225-41e6-a317-0fdcf498d8b2',
name: 'test1',
__typename: "Sometype",
},
},
},
];
const navigationSpy = jest.spyOn(sandboxMock.navigation, 'navigate');
await act(async() => {
jest
.spyOn(useSomethingState, 'default')
.mockReturnValue([
{name:"test1",notes:"notes1",items : mockItems},
true,
jest.fn(),
]);
const { getByRole } = renderComponent({
...props,
},mocks);
fireEvent.click(getByRole('button', { name:"Save" }))
jest.advanceTimersByTime(1000);
});
expect(navigationSpy).toHaveBeenCalled(); //Failing
});
});
useSomethingState 是一个自定义 Hook,它返回 [state,isValid,setState],如果 isValid 为真,它用于启用 saveButton。 state 是一个包含项目的对象,setState 用于添加项目。
这个失败的断言:基本上这会检查 useEffect 中发生的 closeTrowser。由于 useEffect 在获得模拟响应后不会触发, 断言失败
P.S:在 Prod 或 UI 中测试但单元测试失败时,它工作正常。
我不确定你为什么在这里使用假定时器,因为你没有测试任何与时间相关的代码。
相反,我建议您尝试使用 waitFor:
等待断言await waitFor(() => expect(navigationSpy).toHaveBeenCalled())