我无法通过测试来动态更改点击按钮时输入标签的值。

huangapple go评论129阅读模式
英文:

I cannot pass the test to dynamically change the value of the input tag when i clicked the button

问题

我的应用程序代码

  1. export function App() {
  2. const [inputValue, setInputValue] = React.useState("");
  3. const inputRef = React.useRef<HTMLInputElement>(null);
  4. const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
  5. e.preventDefault();
  6. if (inputRef.current) {
  7. inputRef.current.value = inputRef.current.value + "1";
  8. setInputValue(inputRef.current.value);
  9. }
  10. };
  11. return (
  12. <form>
  13. <label htmlFor="password-input" >
  14. 密码
  15. </label>
  16. <input
  17. ref={inputRef}
  18. type="password"
  19. id="password-input"
  20. name="password-input"
  21. value={inputValue}
  22. />
  23. <button
  24. className="insert"
  25. data-testId={1}
  26. onClick={(e) => { handleClick(e) }}>
  27. 输入
  28. </button>
  29. </form>)
  30. }

我的测试代码

  1. test("点击按钮是否会改变输入值?", async () => {
  2. render(<App />);
  3. userEvent.click(await screen.findByTestId(1));
  4. userEvent.click(await screen.findByTestId(1));
  5. expect((await screen.findByLabelText<HTMLInputElement>(`密码`)).value).toHaveLength(2);
  6. userEvent.click(await screen.findByTestId(1));
  7. userEvent.click(await screen.findByTestId(1));
  8. userEvent.click(await screen.findByTestId(1));
  9. userEvent.click(await screen.findByTestId(1));
  10. expect((await screen.findByLabelText<HTMLInputElement>(`密码`)).value).toHaveLength(6);
  11. })

运行测试代码的结果是

  1. expect(received).toHaveLength(expected)
  2. 期望长度: 2
  3. 收到长度: 1
  4. 收到的字符串: "1"
  5. 37 | userEvent.click(await screen.findByTestId(1));
  6. 38 |
  7. > 39 | expect((await screen.findByLabelText<HTMLInputElement>(`密码`)).value).toHaveLength(2);
  8. | ^
  9. 40 |
  10. 41 | userEvent.click(await screen.findByTestId(1));
  11. 42 | userEvent.click(await screen.findByTestId(1));
  12. at Object.toHaveLength (src/test/my.spec.tsx:39:80)
  13. 测试套件: 1 失败, 1 总计
  14. 测试用例: 1 失败, 1 总计

每次我点击按钮时,我期望输入值从""变为"1","11"和"111",但似乎在开发服务器上运行正常,但当我运行测试代码时,输入值始终少于点击次数。如何修复此错误并通过测试?请帮助我...

英文:

My App Code

  1. export function App() {
  2. const [inputValue, setInputValue] = React.useState(&quot;&quot;);
  3. const inputRef = React.useRef&lt;HTMLInputElement&gt;(null);
  4. const handleClick = (e: React.MouseEvent&lt;HTMLButtonElement&gt;) =&gt; {
  5. e.preventDefault();
  6. if (inputRef.current) {
  7. inputRef.current.value = inputRef.current.value + &quot;1&quot;;
  8. setInputValue(inputRef.current.value);
  9. }
  10. };
  11. return (
  12. &lt;form&gt;
  13. &lt;label htmlFor=&quot;password-input&quot; &gt;
  14. 비밀번호
  15. &lt;/label&gt;
  16. &lt;input
  17. ref={inputRef}
  18. type=&quot;password&quot;
  19. id=&quot;password-input&quot;
  20. name=&quot;password-input&quot;
  21. value={inputValue}
  22. /&gt;
  23. &lt;button
  24. className=&quot;insert&quot;
  25. data-testId={1}
  26. onClick={(e) =&gt; { handleClick(e) }}&gt;
  27. 입력
  28. &lt;/button&gt;
  29. &lt;/form&gt;)
  30. }

My test code

  1. test(&quot;Does clicking the button change the input value?&quot;, async () =&gt; {
  2. render(&lt;App /&gt;);
  3. userEvent.click(await screen.findByTestId(1));
  4. userEvent.click(await screen.findByTestId(1));
  5. expect((await screen.findByLabelText&lt;HTMLInputElement&gt;(`비밀번호`)).value).toHaveLength(2);
  6. userEvent.click(await screen.findByTestId(1));
  7. userEvent.click(await screen.findByTestId(1));
  8. userEvent.click(await screen.findByTestId(1));
  9. userEvent.click(await screen.findByTestId(1));
  10. expect((await screen.findByLabelText&lt;HTMLInputElement&gt;(`비밀번호`)).value).toHaveLength(6);
  11. })

As a result of running the test code is

  1. expect(received).toHaveLength(expected)
  2. Expected length: 2
  3. Received length: 1
  4. Received string: &quot;1&quot;
  5. 37 | userEvent.click(await screen.findByTestId(1));
  6. 38 |
  7. &gt; 39 | expect((await screen.findByLabelText&lt;HTMLInputElement&gt;(`비밀번호`)).value).toHaveLength(2);
  8. | ^
  9. 40 |
  10. 41 | userEvent.click(await screen.findByTestId(1));
  11. 42 | userEvent.click(await screen.findByTestId(1));
  12. at Object.toHaveLength (src/test/my.spec.tsx:39:80)
  13. Test Suites: 1 failed, 1 total
  14. Tests: 1 failed, 1 total

Every time I clicked on a button, i expected the input value to be "1", "11" and "111" from "", but it seems to work on dev server, but when i ran the test code, the input value continued to be less than the number of clicks. How can i fix thi error and pass the test?
Please help me...

答案1

得分: 0

  • 应该使用 data-testid,而不是 data-testId

  • click() API 返回一个 Promise,所以你需要像这样使用 await useEvent.click()

  • 不需要使用 data-testid,你可以通过可访问角色('button')和可访问名称('입력')来找到按钮元素。

例如:

index.tsx:

  1. import React from 'react';
  2. export function App() {
  3. const [inputValue, setInputValue] = React.useState('');
  4. const inputRef = React.useRef<HTMLInputElement>(null);
  5. const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
  6. e.preventDefault();
  7. if (inputRef.current) {
  8. inputRef.current.value = inputRef.current.value + '1';
  9. setInputValue(inputRef.current.value);
  10. }
  11. };
  12. return (
  13. <form>
  14. <label htmlFor='password-input'>비밀번호</label>
  15. <input ref={inputRef} type='password' id='password-input' name='password-input' value={inputValue} />
  16. <button
  17. className='insert'
  18. onClick={(e) => {
  19. handleClick(e);
  20. }}
  21. >
  22. 입력
  23. </button>
  24. </form>
  25. );
  26. }

index.test.tsx:

  1. import React from 'react';
  2. import { render, screen } from '@testing-library/react';
  3. import { App } from '.';
  4. import userEvent from '@testing-library/user-event';
  5. test('Does clicking the button change the input value?', async () => {
  6. render(<App />);
  7. const $button = screen.getByRole('button', { name: '입력' });
  8. await userEvent.click($button);
  9. await userEvent.click($button);
  10. let $passwordInput = (await screen.findByLabelText(`비밀번호`)) as HTMLInputElement;
  11. expect($passwordInput.value).toHaveLength(2);
  12. await userEvent.click($button);
  13. await userEvent.click($button);
  14. await userEvent.click($button);
  15. await userEvent.click($button);
  16. expect($passwordInput.value).toHaveLength(6);
  17. expect($passwordInput.value).toBe('111111');
  18. });

测试结果:

  1. console.error
  2. 警告: Failed prop type: You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.
  3. in input (created by App)
  4. in form (created by App)
  5. in App
  6. at printWarning (node_modules/prop-types/checkPropTypes.js:20:15)
  7. PASS stackoverflow/76865066/index.test.tsx (6.41 s)
  8. Does clicking the button change the input value? (116 ms)
  9. -----------|---------|----------|---------|---------|-------------------
  10. File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
  11. -----------|---------|----------|---------|---------|-------------------
  12. All files | 100 | 50 | 100 | 100 |
  13. index.tsx | 100 | 50 | 100 | 100 | 9
  14. -----------|---------|----------|---------|---------|-------------------
  15. Test Suites: 1 passed, 1 total
  16. Tests: 1 passed, 1 total
  17. Snapshots: 0 total
  18. Time: 6.619 s, estimated 7 s
  19. Ran all test suites related to changed files.

包版本:

  1. "@testing-library/react": "^11.2.7",
  2. "@testing-library/user-event": "^14.4.3",
  3. "jest": "^26.6.3",
英文:
  • It should be data-testid, not data-testId.

  • click() API returns a promise, so you need to use it like await useEvent.click().

  • There is no need to use data-testid, you can find the button element by its accessible role(&#39;button&#39;) with accessible name(&#39;입력&#39;)

e.g.

index.tsx:

  1. import React from &#39;react&#39;;
  2. export function App() {
  3. const [inputValue, setInputValue] = React.useState(&#39;&#39;);
  4. const inputRef = React.useRef&lt;HTMLInputElement&gt;(null);
  5. const handleClick = (e: React.MouseEvent&lt;HTMLButtonElement&gt;) =&gt; {
  6. e.preventDefault();
  7. if (inputRef.current) {
  8. inputRef.current.value = inputRef.current.value + &#39;1&#39;;
  9. setInputValue(inputRef.current.value);
  10. }
  11. };
  12. return (
  13. &lt;form&gt;
  14. &lt;label htmlFor=&#39;password-input&#39;&gt;비밀번호&lt;/label&gt;
  15. &lt;input ref={inputRef} type=&#39;password&#39; id=&#39;password-input&#39; name=&#39;password-input&#39; value={inputValue} /&gt;
  16. &lt;button
  17. className=&#39;insert&#39;
  18. onClick={(e) =&gt; {
  19. handleClick(e);
  20. }}
  21. &gt;
  22. 입력
  23. &lt;/button&gt;
  24. &lt;/form&gt;
  25. );
  26. }

index.test.tsx:

  1. import React from &#39;react&#39;;
  2. import { render, screen } from &#39;@testing-library/react&#39;;
  3. import { App } from &#39;.&#39;;
  4. import userEvent from &#39;@testing-library/user-event&#39;;
  5. test(&#39;Does clicking the button change the input value?&#39;, async () =&gt; {
  6. render(&lt;App /&gt;);
  7. const $button = screen.getByRole(&#39;button&#39;, { name: &#39;입력&#39; });
  8. await userEvent.click($button);
  9. await userEvent.click($button);
  10. let $passwordInput = (await screen.findByLabelText(`비밀번호`)) as HTMLInputElement;
  11. expect($passwordInput.value).toHaveLength(2);
  12. await userEvent.click($button);
  13. await userEvent.click($button);
  14. await userEvent.click($button);
  15. await userEvent.click($button);
  16. expect($passwordInput.value).toHaveLength(6);
  17. expect($passwordInput.value).toBe(&#39;111111&#39;);
  18. });

Test result:

  1. console.error
  2. Warning: Failed prop type: You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.
  3. in input (created by App)
  4. in form (created by App)
  5. in App
  6. at printWarning (node_modules/prop-types/checkPropTypes.js:20:15)
  7. PASS stackoverflow/76865066/index.test.tsx (6.41 s)
  8. Does clicking the button change the input value? (116 ms)
  9. -----------|---------|----------|---------|---------|-------------------
  10. File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
  11. -----------|---------|----------|---------|---------|-------------------
  12. All files | 100 | 50 | 100 | 100 |
  13. index.tsx | 100 | 50 | 100 | 100 | 9
  14. -----------|---------|----------|---------|---------|-------------------
  15. Test Suites: 1 passed, 1 total
  16. Tests: 1 passed, 1 total
  17. Snapshots: 0 total
  18. Time: 6.619 s, estimated 7 s
  19. Ran all test suites related to changed files.

package versions:

  1. &quot;@testing-library/react&quot;: &quot;^11.2.7&quot;,
  2. &quot;@testing-library/user-event&quot;: &quot;^14.4.3&quot;,
  3. &quot;jest&quot;: &quot;^26.6.3&quot;,

huangapple
  • 本文由 发表于 2023年8月9日 14:20:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/76865066.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定