简体   繁体   English

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

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

Initial Question初始问题

I have a simple increment/decrement component.我有一个简单的递增/递减组件。

It shows a number count and 2 buttons that either increment or decrements by 1.它显示一个数字计数和 2 个按 1 递增或递减的按钮。

There is also an input;还有一个输入; if a numeric value is supplied in the input then the buttons use the input value instead of 1 to inc/decrement.如果输入中提供了数值,则按钮使用输入值而不是 1 来增加/减少。

I have this test:我有这个测试:

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);
})

The Issue: The updated count here is returning 1 (default in useState ), I expected 4.问题:此处更新的计数返回 1( useState默认值),我预计为 4。

expect(parseInt(input.value, 10)).toBe(4) passes and the input onChange is hooked up. expect(parseInt(input.value, 10)).toBe(4)通过并且输入onChange被连接起来。

The Question: Why is the updated input value not being used?问题:为什么不使用更新的输入值?

Additional Info: Although I'm not sure, I thought maybe it wasn't updating the useState on change, so I also added a keyboard event to hit the enter key on the input, after I changed its value.附加信息:虽然我不确定,但我认为它可能没有在更改时更新useState ,所以我还添加了一个键盘事件以在更改其值后按下输入上的 Enter 键。 I was hoping to further simulate a user and update the state but I had no luck with this.我希望进一步模拟用户并更新状态,但我对此并不走运。

Any help much appreciated!非常感谢任何帮助! Apologies for anything that's out of place, I've only been looking at Jest/RTL the last couple, of days.为任何不合适的地方道歉,我最近几天只在看 Jest/RTL。



Reply Info回复信息

Test Component:测试组件:

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;

Test:测试:

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);
  })
})

You have a typo in your type attribute.您的 type 属性有错别字。 Change this改变这个

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

To this对此

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

And the test will work again.并且测试将再次起作用。 My guess is that by specifying the <input> an invalid type attribute, the library doesn't know which role your input is, so it cannot handle the onchange event properly.我的猜测是,通过指定<input>一个无效的type属性,库不知道您的input是哪个角色,因此它无法正确处理onchange事件。

I'm not sure why updating to the new version of react-scripts and @testing-library/react will fix the problem even if you leave the typo there though.我不知道为什么更新到新版本的react-scripts@testing-library/react会解决这个问题,即使你把错字留在那里。

暂无
暂无

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

相关问题 使用React,Jest,React-Testing-Library测试失败的案例 - Test failing cases with React, Jest, React-Testing-Library Jest + react-testing-library:警告更新未包含在 act() 中 - Jest + react-testing-library: Warning update was not wrapped in act() 如何使用 React、Jest 和 React-testing-library 为带有令牌的 api 调用编写单元测试? - How can I write unit test for api call with token using React, Jest and React-testing-library? 如何使用 react-testing-library 和 jest 测试 function 组件中的 state - How to test state within function component with react-testing-library and jest 使用 Jest 和 react-testing-library 测试具有大量输入字段的表单的正确方法是什么? - What is the proper way to test a form with a lot of input fields using Jest and react-testing-library? 编写测试以使用 jest 和 react-testing-library 检查本地 setState 调用 - Write test to check local setState call with jest and react-testing-library 使用 react-testing-library 和 jest 测试是否调用了 prop 函数 - Testing if a prop function was called using react-testing-library and jest 使用 Jest + react-testing-library 测试异步 `componentDidMount()` - Testing async `componentDidMount()` with Jest + react-testing-library 更新未包含在 act(...) 中,并且模拟 function 未触发。 反应测试库,开玩笑 - Update not wrapped in act(…) and the mock function not firing. react-testing-library, jest 如何在Jest和react-testing-library中使用react-hook - How to use react-hooks with Jest and react-testing-library
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM