简体   繁体   English

如何测试使用 React 测试库检查的复选框?

[英]How to test checkbox checked with React Testing Library?

are there anyone see the problem here?有没有人看到这里的问题? If I put checked in state on change it works.如果我在 state 中进行检查,则可以进行更改。 But I don't want to duplicate the checked state data and watch it every single props change.但我不想复制检查过的 state 数据并观察每一个道具的变化。

Parent components gets the latest checked information and put it in own state and if parent isChecked change, FormCheckBox isChecked changes.父组件获取最新的检查信息并放入自己的state,如果父组件isChecked改变,FormCheckBox isChecked改变。 I think, it works async and when I reach latest line of my test code, parent update does not finish, so I see the stale isChecked.我认为,它是异步工作的,当我到达我的测试代码的最新行时,父更新没有完成,所以我看到过时的 isChecked。

    export default function FormCheckBox(props: IFormCheckBoxProps) {
      const { onChange, label, isChecked, error, errorModelLabel = '' } = props
    
      const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
        onChange(event.currentTarget.checked)
      }
    
      const errorMsg = getFormErrorMsg(error, errorModelLabel)
    
      return (
        <FormGroup
          as={Row}
          className={cx('mb-3', { 'is-invalid': errorMsg })}
          controlId="catalogDescription"
          data-testid="slvy-formcheckbox"
        >
          <FormLabel column className="d-flex align-items-center justify-content-end fw-bold" sm={2}>
            {label}
          </FormLabel>
          <Col className="d-flex align-items-center" sm={10}>
            <input
              checked={isChecked}
              className={cx('checkbox', { 'is-invalid': errorMsg })}
              type="checkbox"
              onChange={handleChange}
            />
            <Form.Control.Feedback type="invalid">{errorMsg}</Form.Control.Feedback>
          </Col>
        </FormGroup>
      )
    }


 it('checkbox must use fireEvent.click', async () => {
    const handleChange = jest.fn()
    props.isChecked = false
    props.onChange = handleChange

    const { container } = render(<FormCheckBox {...props} />)
    const checkbox = container.querySelectorAll("input[type='checkbox']")[0] as HTMLInputElement

    fireEvent.click(checkbox)
    expect(handleChange).toHaveBeenCalledTimes(1)
    
    expect(checkbox.checked).toBe(true)
  })

Since the FormCheckBox is a controlled component, the input's value is always driven by the React state.由于FormCheckBox是一个受控组件,因此输入值始终由 React state 驱动。 So you need a wrapper component to provide this state.所以你需要一个包装器组件来提供这个 state。 In your test case, even though the mock handleChange function is called, we need to update the isChecked state so that the FormCheckBox component will re-render with this new state.在您的测试用例中,即使调用了模拟handleChange function,我们也需要更新isChecked state 以便FormCheckBox组件将使用这个新的 Z9ED39E2EA931586B56A985A6942EF 重新呈现。

Eg例如

index.tsx : index.tsx

import React from 'react';

export default function FormCheckBox({ onChange, isChecked }) {

  const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    onChange(event.currentTarget.checked);
  };

  return <input checked={isChecked} type="checkbox" onChange={handleChange} />;
}

To keep things simple.为了保持简单。 I removed the irrelevant code.我删除了不相关的代码。

index.test.tsx : index.test.tsx

import { fireEvent, render } from '@testing-library/react';
import React, { useState } from 'react';
import FormCheckBox from './';

describe('73184212', () => {
  test('should pass', () => {
    const Wrap = () => {
      const [isChecked, setIsChecked] = useState(false);
      return <FormCheckBox isChecked={isChecked} onChange={() => setIsChecked(!isChecked)} />;
    };
    const { container } = render(<Wrap />);
    const checkbox = container.querySelectorAll("input[type='checkbox']")[0] as HTMLInputElement;
    fireEvent.click(checkbox);
    expect(checkbox.checked).toBe(true);
  });
});

Test result:测试结果:

 PASS  stackoverflow/73184212/index.test.tsx (10.998 s)
  73184212
    ✓ should pass (30 ms)

-----------|---------|----------|---------|---------|-------------------
File       | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-----------|---------|----------|---------|---------|-------------------
All files  |     100 |      100 |     100 |     100 |                   
 index.tsx |     100 |      100 |     100 |     100 |                   
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        11.607 s

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM