Initial Question
I have a simple increment/decrement component.
It shows a number count and 2 buttons that either increment or decrements by 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.
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.
expect(parseInt(input.value, 10)).toBe(4) passes and the input onChange is hooked up.
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. 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.
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);
})
})