testing-library / react-hooks-testing-library

🐏 Simple and complete React hooks testing utilities that encourage good testing practices.
https://react-hooks-testing-library.com
MIT License
5.25k stars 233 forks source link

How to test context with useReducer #124

Closed engp8691 closed 5 years ago

engp8691 commented 5 years ago

The following are my React Context with useReducer implementation. I want to test my consumer. But It does not work. Would you please help me figure out my mistakes. Thank you!

CountInterface.test.js

import React from 'react'; import { render, cleanup } from '@testing-library/react'; import { renderHook, act } from '@testing-library/react-hooks';

import 'jest-dom/extend-expect';

import { CountContext, CountProvider, useCountContext, countReducer } from '../CountContext'; import PlusMinus from '../CountInterface';

afterEach(cleanup)

test('NameConsumer shows value from provider', () => { const initialState = {count: 0}; const { result } = renderHook(() => React.useReducer(countReducer, initialState)); const [myState, dispatch] = result.current;

const tree = (
    <CountContext.Provider value={[myState, dispatch]} >
        <PlusMinus />
    </CountContext.Provider>
);
const { getByText, getAllByTestId, getByTestId, container } = render(tree);

const mybutton = getByText(/Sub/i);

try {
    act(() => {
        dispatch({ type: "INCREASE"});
    });
} catch (e) {
}

// I tried to watch the console.log in the CountInterface.js, but I do not see and log printing. // So it means the dispatched action was not updating the state in the consumer component. // Can someone help me figure it out on how to do my test program for the CountInterface.js // component? I want to dispatch an action and check the status of state/count value. })


setupTests.js import '@testing-library/react/cleanup-after-each' import 'jest-dom/extend-expect'


App.js import React from 'react'; import PlusMinus from './CountInterface'; import { CountProvider } from './CountContext'

const App = () => { return (

);

}

export default App;

CountContext.js import React from 'react'

const countReducer = (state = { count: 0 }, action) => { switch (action.type) { case "INCREASE": console.log("To increase") return { count: state.count + 1 }; case "DECREASE": console.log("To decrease") return { count: state.count - 1 }; default: return state } }

const CountContext = React.createContext({ count: 0 });

const CountProvider = ({ children }) => { const [state, dispatch] = React.useReducer(countReducer, { count: 0 });

return (
    <CountContext.Provider value={[state, dispatch]}>
        {children}
    </CountContext.Provider>
)

}

const useCountContext = () => { const context = React.useContext(CountContext) if (context === undefined) { throw new Error('useCountState must be used within a CountProvider') } return context }

export { CountContext, CountProvider, useCountContext, countReducer }


CountInterface.js import React from 'react'; import { useCountContext } from './CountContext';

const PlusMinus = (props) => { const [state, dispatch] = useCountContext();

const onAdd = (e) => {
    dispatch({ type: "INCREASE" });
}

const onSub = (e) => {
    dispatch({ type: "DECREASE" });
}

console.log(11111111111,  state.count);

return (
    <div>
        <span>Count: {state.count} </span>
        <div>
            <button onClick={onAdd}>Add</button>
            <button onClick={onSub}>Sub</button>
        </div>
    </div>
);

}

export default PlusMinus;

octavianusb commented 4 years ago

Why was this issue closed without any answer? I have the same problem and it seems like the state from <CountContext.Provider value={[state, dispatch]}> is not updated when a dispatch is made

mpeyper commented 4 years ago

It was closed by the author (presumably shortly after it was opened).

It's probably best if you open a new issue with the specific details of your test so I can help you out.