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

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

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

问题

我的应用程序代码

export function App() {
    const [inputValue, setInputValue] = React.useState("");
    const inputRef = React.useRef<HTMLInputElement>(null);

    const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
        e.preventDefault();
        if (inputRef.current) {
            inputRef.current.value = inputRef.current.value + "1";
            setInputValue(inputRef.current.value);
        }
    };

    return (
        <form>
            <label htmlFor="password-input" >
                密码
            </label>
            <input
                ref={inputRef}
                type="password"
                id="password-input"
                name="password-input"
                value={inputValue}
            />
            <button
                className="insert"
                data-testId={1}
                onClick={(e) => { handleClick(e) }}>
                输入
            </button>
        </form>)
}

我的测试代码

test("点击按钮是否会改变输入值?", async () => {
        render(<App />);

        userEvent.click(await screen.findByTestId(1));
        userEvent.click(await screen.findByTestId(1));

        expect((await screen.findByLabelText<HTMLInputElement>(`密码`)).value).toHaveLength(2);

        userEvent.click(await screen.findByTestId(1));
        userEvent.click(await screen.findByTestId(1));
        userEvent.click(await screen.findByTestId(1));
        userEvent.click(await screen.findByTestId(1));

        expect((await screen.findByLabelText<HTMLInputElement>(`密码`)).value).toHaveLength(6);
    })

运行测试代码的结果是

    expect(received).toHaveLength(expected)

    期望长度: 2
    收到长度: 1
    收到的字符串: "1"

      37 |         userEvent.click(await screen.findByTestId(1));
      38 |
    > 39 |         expect((await screen.findByLabelText<HTMLInputElement>(`密码`)).value).toHaveLength(2);
         |                                                                                ^
      40 |
      41 |         userEvent.click(await screen.findByTestId(1));
      42 |         userEvent.click(await screen.findByTestId(1));

      at Object.toHaveLength (src/test/my.spec.tsx:39:80)

测试套件: 1 失败, 1 总计
测试用例: 1 失败, 1 总计

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

英文:

My App Code

export function App() {
    const [inputValue, setInputValue] = React.useState(&quot;&quot;);
    const inputRef = React.useRef&lt;HTMLInputElement&gt;(null);

    const handleClick = (e: React.MouseEvent&lt;HTMLButtonElement&gt;) =&gt; {
        e.preventDefault();
        if (inputRef.current) {
            inputRef.current.value = inputRef.current.value + &quot;1&quot;;
            setInputValue(inputRef.current.value);
        }
    };

    return (
        &lt;form&gt;
            &lt;label htmlFor=&quot;password-input&quot; &gt;
                비밀번호
            &lt;/label&gt;
            &lt;input
                ref={inputRef}
                type=&quot;password&quot;
                id=&quot;password-input&quot;
                name=&quot;password-input&quot;
                value={inputValue}
            /&gt;
            &lt;button
                className=&quot;insert&quot;
                data-testId={1}
                onClick={(e) =&gt; { handleClick(e) }}&gt;
                입력
            &lt;/button&gt;
        &lt;/form&gt;)
}

My test code

test(&quot;Does clicking the button change the input value?&quot;, async () =&gt; {
        render(&lt;App /&gt;);

        userEvent.click(await screen.findByTestId(1));
        userEvent.click(await screen.findByTestId(1));

        expect((await screen.findByLabelText&lt;HTMLInputElement&gt;(`비밀번호`)).value).toHaveLength(2);

        userEvent.click(await screen.findByTestId(1));
        userEvent.click(await screen.findByTestId(1));
        userEvent.click(await screen.findByTestId(1));
        userEvent.click(await screen.findByTestId(1));

        expect((await screen.findByLabelText&lt;HTMLInputElement&gt;(`비밀번호`)).value).toHaveLength(6);
    })

As a result of running the test code is

    expect(received).toHaveLength(expected)

    Expected length: 2
    Received length: 1
    Received string: &quot;1&quot;

      37 |         userEvent.click(await screen.findByTestId(1));
      38 |
    &gt; 39 |         expect((await screen.findByLabelText&lt;HTMLInputElement&gt;(`비밀번호`)).value).toHaveLength(2);
         |                                                                                ^
      40 |
      41 |         userEvent.click(await screen.findByTestId(1));
      42 |         userEvent.click(await screen.findByTestId(1));

      at Object.toHaveLength (src/test/my.spec.tsx:39:80)

Test Suites: 1 failed, 1 total
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:

import React from 'react';

export function App() {
	const [inputValue, setInputValue] = React.useState('');
	const inputRef = React.useRef<HTMLInputElement>(null);

	const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
		e.preventDefault();
		if (inputRef.current) {
			inputRef.current.value = inputRef.current.value + '1';
			setInputValue(inputRef.current.value);
		}
	};

	return (
		<form>
			<label htmlFor='password-input'>비밀번호</label>
			<input ref={inputRef} type='password' id='password-input' name='password-input' value={inputValue} />
			<button
				className='insert'
				onClick={(e) => {
					handleClick(e);
				}}
			>
				입력
			</button>
		</form>
	);
}

index.test.tsx:

import React from 'react';
import { render, screen } from '@testing-library/react';
import { App } from '.';
import userEvent from '@testing-library/user-event';

test('Does clicking the button change the input value?', async () => {
	render(<App />);

	const $button = screen.getByRole('button', { name: '입력' });

	await userEvent.click($button);
	await userEvent.click($button);

	let $passwordInput = (await screen.findByLabelText(`비밀번호`)) as HTMLInputElement;

	expect($passwordInput.value).toHaveLength(2);

	await userEvent.click($button);
	await userEvent.click($button);
	await userEvent.click($button);
	await userEvent.click($button);

	expect($passwordInput.value).toHaveLength(6);
	expect($passwordInput.value).toBe('111111');
});

测试结果:

  console.error
    警告: 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`.
        in input (created by App)
        in form (created by App)
        in App

      at printWarning (node_modules/prop-types/checkPropTypes.js:20:15)

 PASS  stackoverflow/76865066/index.test.tsx (6.41 s)
  ✓ Does clicking the button change the input value? (116 ms)

-----------|---------|----------|---------|---------|-------------------
File       | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-----------|---------|----------|---------|---------|-------------------
All files  |     100 |       50 |     100 |     100 |                   
 index.tsx |     100 |       50 |     100 |     100 | 9                 
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        6.619 s, estimated 7 s
Ran all test suites related to changed files.

包版本:

"@testing-library/react": "^11.2.7",
"@testing-library/user-event": "^14.4.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:

import React from &#39;react&#39;;

export function App() {
	const [inputValue, setInputValue] = React.useState(&#39;&#39;);
	const inputRef = React.useRef&lt;HTMLInputElement&gt;(null);

	const handleClick = (e: React.MouseEvent&lt;HTMLButtonElement&gt;) =&gt; {
		e.preventDefault();
		if (inputRef.current) {
			inputRef.current.value = inputRef.current.value + &#39;1&#39;;
			setInputValue(inputRef.current.value);
		}
	};

	return (
		&lt;form&gt;
			&lt;label htmlFor=&#39;password-input&#39;&gt;비밀번호&lt;/label&gt;
			&lt;input ref={inputRef} type=&#39;password&#39; id=&#39;password-input&#39; name=&#39;password-input&#39; value={inputValue} /&gt;
			&lt;button
				className=&#39;insert&#39;
				onClick={(e) =&gt; {
					handleClick(e);
				}}
			&gt;
				입력
			&lt;/button&gt;
		&lt;/form&gt;
	);
}

index.test.tsx:

import React from &#39;react&#39;;
import { render, screen } from &#39;@testing-library/react&#39;;
import { App } from &#39;.&#39;;
import userEvent from &#39;@testing-library/user-event&#39;;

test(&#39;Does clicking the button change the input value?&#39;, async () =&gt; {
	render(&lt;App /&gt;);

	const $button = screen.getByRole(&#39;button&#39;, { name: &#39;입력&#39; });

	await userEvent.click($button);
	await userEvent.click($button);

	let $passwordInput = (await screen.findByLabelText(`비밀번호`)) as HTMLInputElement;

	expect($passwordInput.value).toHaveLength(2);

	await userEvent.click($button);
	await userEvent.click($button);
	await userEvent.click($button);
	await userEvent.click($button);

	expect($passwordInput.value).toHaveLength(6);
	expect($passwordInput.value).toBe(&#39;111111&#39;);
});

Test result:

  console.error
    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`.
        in input (created by App)
        in form (created by App)
        in App

      at printWarning (node_modules/prop-types/checkPropTypes.js:20:15)

 PASS  stackoverflow/76865066/index.test.tsx (6.41 s)
  ✓ Does clicking the button change the input value? (116 ms)

-----------|---------|----------|---------|---------|-------------------
File       | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-----------|---------|----------|---------|---------|-------------------
All files  |     100 |       50 |     100 |     100 |                   
 index.tsx |     100 |       50 |     100 |     100 | 9                 
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        6.619 s, estimated 7 s
Ran all test suites related to changed files.

package versions:

&quot;@testing-library/react&quot;: &quot;^11.2.7&quot;,
&quot;@testing-library/user-event&quot;: &quot;^14.4.3&quot;,
&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:

确定