英文:
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("");
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>)
}
My test code
test("Does clicking the button change the input value?", 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);
})
As a result of running the test code is
expect(received).toHaveLength(expected)
Expected length: 2
Received length: 1
Received string: "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)
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
, notdata-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('button'
) with accessible name('입력'
)
e.g.
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');
});
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:
"@testing-library/react": "^11.2.7",
"@testing-library/user-event": "^14.4.3",
"jest": "^26.6.3",
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论