使用 Jest 和 React 测试库测试 Apollo React Hooks
Posted
技术标签:
【中文标题】使用 Jest 和 React 测试库测试 Apollo React Hooks【英文标题】:Testing Apollo React Hooks with Jest & React Testing Library 【发布时间】:2020-03-24 16:29:30 【问题描述】:我有一个使用 Apollo 突变钩子的表单:
import React from 'react'
import useFormik from 'formik'
import useLoginMutation from '../generated'
const LoginContainer = () =>
const [loginMutation, data, loading, error ] = useLoginMutation()
const formik = useFormik(
initialValues:
email: '',
password: '',
,
onSubmit: values =>
loginMutation(
variables:
input:
email: String(values.email).trim(),
password: values.password,
,
,
)
,
)
return (
<form
onSubmit=event =>
event.preventDefault()
formik.handleSubmit(event)
>
<input
data-testid="login-email-input"
name="email"
placeholder="Email address"
// label="Email"
required
type="email"
value=formik.values.email
onChange=formik.handleChange
/>
<input
data-testid="login-password-input"
name="password"
placeholder="password"
// label="Password"
required
type="password"
value=formik.values.password
onChange=formik.handleChange
/>
<button data-testid="login-submit-input" type="submit">
LOGIN
</button>
</form>
)
export default LoginContainer
我试图确保在用户填写表单并单击提交按钮时调用登录突变。
测试有时会成功运行,有时会失败。我怀疑 loginMutation 承诺在运行期望块之前没有得到解决。
控制台也有以下警告:
Warning: An update to LoginContainer inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() =>
/* fire events that update state */
);
/* assert on the output */
这是测试:
describe('login container', () =>
let loginMutationCalled = false
const variables =
input:
email: 'test@example.com',
password: '123',
,
const result = () =>
loginMutationCalled = true
return
data:
Login:
accountId: '123',
,
,
const mocks = [
request:
query: LOGIN_MUTATION,
variables,
,
result,
,
]
it('should call the login mutation', async () =>
await act(async () =>
const findByTestId = render(
<MockedProvider mocks=mocks addTypename=false>
<LoginContainer />
</MockedProvider>,
)
fireEvent.change(await findByTestId('login-email-input'),
target:
value: 'test@example.com',
,
)
fireEvent.change(await findByTestId('login-password-input'),
target:
value: '123',
,
)
await wait(async () =>
fireEvent.click(await findByTestId('login-submit-input')),
)
)
expect(loginMutationCalled).toBe(true)
)
)
如何确保在运行断言之前已解决 loginMutation 承诺?
【问题讨论】:
【参考方案1】:请查看我的 GitHub https://github.com/Arit143/mytube-ui/blob/master/src/pages/List.spec.tsx 以获取 async act wait
。通常,我将行为包装起来并在一个函数中等待,然后等待它完成。如果您觉得登录解析花费了很多时间,您可以增加wait
的数量。以 GitHub URL 为例,如果您仍然遇到问题,请告诉我。
【讨论】:
以上是关于使用 Jest 和 React 测试库测试 Apollo React Hooks的主要内容,如果未能解决你的问题,请参考以下文章
在 TypeScript 中使用 NextJS 设置 Jest + React 测试库 -- 设置 upp jest.config.js 时出错
如何使用 Jest 和 react-testing-library 测试 react-dropzone?
fireEvent.keyDown 在我的 Jest + React 测试库测试中没有按预期工作