Jest/react-testing-library:单击按钮未更新测试中的值

Jest/react-testing-library: Clicking a button didn't update the value in test

初始问题

我有一个简单的 increment/decrement 组件。

它显示了一个数字计数和 2 个递增或递减 1 的按钮。

还有一个输入;如果输入中提供了数值,则按钮使用输入值而不是 1 到 inc/decrement.

我有这个测试:

it(`should increment by input value, if value > 0`, () => {
  const { input } = setup();

  // Change input value to 4
  fireEvent.change(input, {target: { value: 4}});

  // Find and click +n button
  const btn = screen.getByText(`+n`);
  fireEvent.click(btn);

  // Find and check updated count
  const updatedCount = parseInt(screen.getByTestId(`count`).textContent, 10)
  expect(updatedCount).toBe(4);
})

问题: 这里更新后的计数返回 1(useState 中的默认值),我预计是 4。

expect(parseInt(input.value, 10)).toBe(4) 通过,输入 onChange 已连接。

问题:为什么更新后的输入值没有被使用?

附加信息:虽然我不确定,但我想也许它没有更新 useState 更改,所以我还添加了一个键盘事件在我改变它的值之后,点击输入上的回车键。我希望进一步模拟用户并更新状态,但我没有运气。

非常感谢任何帮助!对于任何不合适的地方,我深表歉意,我最近几天一直在看 Jest/RTL。



回复信息

测试组件:

import React, { useState } from "react";

const MyTest = () => {
  const [count, setCount] = useState(0);
  const [value, setValue] = useState(1);

  const incCount = (n) => {
    if (n !== 0) {
      count + n <= 10 && setCount((currCount) => currCount + n);
      return;
    }

    if (count < 10) setCount((currCount) => currCount + 1);
  };
  const decCount = (n) => {
    if (n !== 0) {
      count - n >= 0 && setCount((currCount) => currCount - n);
      return;
    }

    if (count > 0) {
      setCount((currCount) => currCount - 1);
    }
  };

  return (
    <>
      <div>value: {value}</div>
      <div data-testid="count">{count}</div>

      <br />

      <label htmlFor="inp">N Input</label>
      <br />
      <input
        type="texts"
        placeholder="inc or dec by num"
        id="inp"
        value={value}
        onChange={(e) => setValue(e.target.value)}
      />
      <br />
      <button type="button" onClick={() => decCount(parseInt(value))}>
        -n
      </button>
      <button type="button" onClick={() => incCount(parseInt(value))}>
        +n
      </button>
    </>
  );
};

export default MyTest;

测试:

import React from 'react';
import {screen, fireEvent, render, cleanup, waitFor} from '@testing-library/react';
import "@testing-library/jest-dom/extend-expect";
import MyTest from './myTest';

describe(`Increment and decrement the count when relevant button is pressed`, () => {
  // Get component
  const setup = () => {
    const utils = render(<MyTest />)
    const initCount = parseInt(screen.getByTestId(`count`).textContent, 10)
    const input = screen.getByLabelText(`N Input`);
    return {
      initCount,
      input,
      ...utils
    }
  };

  // ...other tests here

  it(`should increment by input value, if value > 0`, () => {
    const { input } = setup();

    // Change input value to 4
    fireEvent.change(input, {target: { value: 4}});

    // Find and click +n button
    const btn = screen.getByText(`+n`);
    fireEvent.click(btn);

    // Find and check updated count
    const updatedCount = parseInt(screen.getByTestId(`count`).textContent, 10)
    expect(updatedCount).toBe(4);
  })
})

您的类型属性中有错字。改变这个

<input type="texts" {...} />

对此

<input type="text" {...} />

并且测试将再次运行。我的猜测是,通过指定 <input> 一个无效的 type 属性,库不知道 role 你的 input 是哪个,所以它无法处理 onchange 事件正常。

我不确定为什么更新到 react-scripts@testing-library/react 的新版本会解决问题,即使您在那里留下错字也是如此。