Skip to content

Unmount does not update the result of calling setter of context. #804

@hoon0422

Description

@hoon0422
  • react-hooks-testing-library version: ^7.0.2
  • react version: ^16.6
  • react-dom version (if applicable): ^16.6
  • react-test-renderer version (if applicable): ^16.8.4
  • node version: 12.18.1
  • npm (or yarn) version: 6.14.5

What you did:

What I wanted to do is to test context values for each hook call or unmount. This bug happens when I call unmount.

What happened:

The test library does not update context value.

Reproduction:

First of all, I want to say that I know this reproduction code is not practical, but the issue from the reproduction code is same with the issue from code in my real project.

Counter.jsx

import React, { useState, useEffect, useContext, createContext } from 'react';

const CounterContext = createContext(0);

export const CounterProvider = ({ children }) => {
    const [value, setValue] = useState(0);
    return <CounterContext.Provider value={{ value, setValue }}>{children}</CounterContext.Provider>;
};

// This hook is what I want to test
export const useCounter = () => {
    const { value, setValue } = useContext(CounterContext);

    useEffect(() => {
        // This clean-up function is what I want to test
        return () => {
            setValue(0);
        };
    }, []);

    return { value, setValue };
};

export const Counter = () => {
    const { value, setValue } = useCounter();

    return (
        <div>
            <div>{value}</div>
            <div>
                <button onClick={() => setValue(value + 1)}>+</button>
                <button onClick={() => setValue(value - 1)}>-</button>
            </div>
        </div>
    );
};

test_Counter.test.js

import { CounterProvider, useCounter } from './Counter';
import { renderHook } from '@testing-library/react-hooks';
import { act } from 'react-test-renderer';

describe('test counter', () => {
    it('test useCounter', () => {
        const { result, unmount } = renderHook(
            () => { return useCounter(); },
            { wrapper: CounterProvider },
        );
        act(() => {
            result.current.setValue(1)
        });
        expect(result.current.value).toEqual(1);  // passed as expected
        unmount();
        expect(result.current.value).toEqual(0);  // failed, which is supposed to be passed. The value is still 1
    });
});

Problem description:

When unmount is called on the test, the cleanup function defined at useEffect at useCounter must be called, and I confirmed that the cleanup function is called in reality. But it does not update result.current when unmount is called. So, the value is 1, which is supposed to be 0. I tried the code below:

act(() => { unmount(); });

But the result was same.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions