pin*_*ndi 9 reactjs react-testing-library
我是测试新手,我正在尝试使用反应测试库来测试我的应用程序。我遇到的第一个问题是测试组件内部的函数,例如事件处理程序。我发现了一些示例,其中函数(事件处理程序)作为 props 在组件中传递,但如果可能的话我不想这样做。
\n我的组件:
\nimport React, { useState } from 'react';\nimport { Redirect } from 'react-router-dom';\nimport { connect } from 'react-redux';\nimport PropTypes from 'prop-types';\n\nimport { login } from 'actions/auth';\nimport Wrapper from './styled/Wrapper';\nimport Button from './styled/Button';\nimport Title from './styled/Title';\nimport { FormWrapper, StyledForm, FormField } from './styled/Form'\nimport Input from './styled/Input';\nimport Link from './styled/Link';\n\n\nconst Login = (props) => {\n const [formData, setFormData] = useState({\n email: '',\n password: ''\n });\n\n const { email, password } = formData;\n\n const onChange = e => setFormData({ ...formData, [e.target.name]: e.target.value });\n\n const onSubmit = e => {\n e.preventDefault();\n props.login(email, password);\n }\n\n if (props.isAuthenticated) {\n return <Redirect to='/' />\n }\n\n return (\n <Wrapper color='#F2F2F2'>\n <FormWrapper>\n <Title>Log In</Title>\n <StyledForm data-testid='auth-form' onSubmit={e => onSubmit(e)}>\n <FormField>\n <Input\n placeholder='Email'\n type='email'\n name='email'\n value={email}\n onChange={e => onChange(e)}\n required\n />\n </FormField>\n <FormField>\n <Input\n placeholder='Password'\n type='password'\n name='password'\n value={password}\n onChange={e => onChange(e)}\n required\n />\n </FormField>\n <Button type='submit' marginTop='6%'>LOG IN</Button>\n </StyledForm>\n <p>Don't have an account? <Link to='/register'>Sign Up!</Link> </p>\n </FormWrapper>\n </Wrapper>\n )\n}\n\nLogin.propTypes = {\n login: PropTypes.func.isRequired,\n isAuthenticated: PropTypes.bool\n}\n\nconst mapStateToProps = state => ({\n isAuthenticated: state.auth.isAuthenticated\n});\n\nexport default connect(mapStateToProps, { login })(Login);\nRun Code Online (Sandbox Code Playgroud)\n我的测试文件:
\nimport React from 'react';\nimport { render, cleanup, fireEvent } from '@testing-library/react';\nimport { Provider } from 'react-redux';\nimport { BrowserRouter as Router } from 'react-router-dom';\nimport store from '../../store';\n\nimport Login from '../Login';\n\n\nafterEach(cleanup);\nconst onChange = jest.fn();\n\n\ntest('<Login>', () => {\n\n const { queryByTestId, getByPlaceholderText, getByText, debug } =\n render(\n <Provider store={store}>\n <Router>\n <Login />\n </Router>\n </Provider>);\n\n expect(queryByTestId('auth-form')).toBeTruthy();\n\n fireEvent.change(getByPlaceholderText('Email'), {\n target: { value: 'test@yahoo.com' },\n });\n fireEvent.change(getByPlaceholderText('Password'), {\n target: { value: 'testpassword' },\n });\n\n fireEvent.click(getByText('LOG IN'));\n expect(onChange).toHaveBeenCalledTimes(1);\n\n});\nRun Code Online (Sandbox Code Playgroud)\n测试输出:
\n FAIL src/components/__tests__/Login.test.js\n \xe2\x9c\x95 <Login> (125 ms)\n\n \xe2\x97\x8f <Login>\n\n expect(jest.fn()).toHaveBeenCalledTimes(expected)\n\n Expected number of calls: 1\n Received number of calls: 0\n\n 32 | \n 33 | fireEvent.click(getByText('LOG IN'));\n > 34 | expect(onChange).toHaveBeenCalledTimes(1);\n | ^\n 35 | \n 36 | });\n\n at Object.<anonymous>.test (src/components/__tests__/Login.test.js:34:22)\n\nTest Suites: 1 failed, 1 total\nTests: 1 failed, 1 total\nSnapshots: 0 total\nTime: 6.013 s\nRan all test suites related to changed files.\n\nWatch Usage: Press w to show more.\nRun Code Online (Sandbox Code Playgroud)\n有没有一种方法可以使 onSubmit 函数可供测试访问,而无需将其作为 prop 传递?
\nReact 测试库的要点是,编写类似于用户如何使用应用程序的测试非常容易。这是我们想要达到的目标,让我们充满信心,也是业界所提倡的。我们编写测试是为了提高对我们应用程序的信心,而不是为了扩大覆盖范围。
考虑到上述情况,您不应该使用toHaveBeenCalledTimes相反的方法,您应该测试触发该功能的视觉结果onChange。根据您共享的代码,我不知道成功登录后会呈现什么,但对于我们的用例,假设文本Welcome, User!会呈现。
您可以像现在一样触发事件,而不是使用 进行测试haveBeenCalled,而是使用以下命令:
expect(getByText('Welcome, User!').toBeInTheDocument();
这将为您提供充分的信心,而不是测试函数是否被调用,这不会给您足够的信心,因为如果函数的实现不正确怎么办?
| 归档时间: |
|
| 查看次数: |
21893 次 |
| 最近记录: |