简体   繁体   中英

Problems using the same function of a custom hook while testing with enzyme using hookRender() and act()

So i have this custom hook: (it just increase, decrease and reset)

import { useState } from 'react';
export const useCounter = (initialState = 1) => {

    const [counter, setCounter] = useState(initialState);
    const increase = (factor = 1) =>{
        setCounter(counter + factor);
    }
    const decrease = (factor = 1) =>{
        setCounter(counter - factor);
    }
    const reset = () =>{
        setCounter(initialState)
    }
    return {
        counter,
        increment,
        decrease,
        reset
    };
};

I would like to test it by calling decrease two time, but it does not do the same effect twice, if I just put decrease() once and value expected to be 99,it works and the test pass. But i was wondering if it is possible to call decrease() twice. I leave the test below.

import "@testing-library/jest-dom";
import { renderHook, act } from "@testing-library/react-hooks";
import { useCounter } from "../../hooks/useCounter";

describe("Test useCounter", () => {
    test("should decrease two times", () => {
        const { result, rerender } = renderHook(() => useCounter(100));
        const { decrease } = result.current;
        act(() => {
            decrease();
            decrease();
        });

        const { counter } = result.current;
        expect(counter).toBe(98);
    });
});

Your issue is that you are treating state like it is synchronous, but it is not.

State does not update until a re-render happens.

When you call decrease() twice, you are essentially saying:

setCounter(100 - 1)
setCounter(100 - 1)

No matter how many times you call it, the counter will only decrement by 1.

This is because the counter state value doesn't change during the same render.

To use the most up to date value when setting state, you need to change your set state to use a callback function:

setCounter(prev => prev - factor)

This will work as expected.

In general, you should always use a callback function when the new state value depends on the old state value. In your case, the new value uses the old value, so you should be using a callback function.

You should also change your increase function in the same way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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