dai-shi / react-hooks-global-state

[NOT MAINTAINED] Simple global state for React with Hooks API without Context API
https://www.npmjs.com/package/react-hooks-global-state
MIT License
1.1k stars 62 forks source link

Mocking useGlobalState with jest? #48

Closed k-patton closed 2 years ago

k-patton commented 4 years ago

Hi, I was wondering if anyone has a way to mock this store for testing purposes? I have a page that renders differently depending on the contents of the store. I'm currently using jest and RTL. Thanks!

dai-shi commented 4 years ago

Hi, that's a good question. I'm not super experienced with mocking, so I wish someone else would jump in this topic.

What I would imagine is to a) mock the hook at module level, or b) use another createGlobalState for testing.

k-patton commented 4 years ago

Hi so this might not work for every scenario, but in this case I was overthinking it. I was able to get the tests I needed by just setting the global state to my test values right in the beginning of my test. It's a "set" not a "mock" but it works.

k-patton commented 4 years ago

On another testing note, has anyone heard of a way to see the current state of the store? Kind of like redux dev tools?

dai-shi commented 4 years ago

It does support redux devtools with createStore. https://github.com/dai-shi/react-hooks-global-state/blob/0ae0dd399ee467bff1f30d791a559ac06ae5727d/examples/08_thunk/src/state.ts#L62 It should work for basic functionality.


Speaking of devtools, I maintain another library zustand which is similar to react-hooks-global-state, but more flexible (because I made react-hooks-global-state to provide api that will never be misused, it's limited in a sense.) Just yesterday, I fixed the devtools module in zustand, which should be more stable. It's not released yet, but you might want to have a look.

gary-menzel commented 4 years ago

@k-patton I have exposed the getGlobalState and getState at the window level - so I can actually call window.getGlobalState() (for example) and see a console log of things. You could use those to create your own dev panel in your application as well. Kent Dodds has some interesting examples of using his testing-library for doing things like that... https://kentcdodds.com/blog/make-your-own-dev-tools/

gary-menzel commented 4 years ago

also - we have just taken a similar approach in our Jest testing.

We actually wrap a lot of functions in an "api" - including the useGlobalState - so we can initialise the global state with anything we want in our tests (including using all our default state).

semonec commented 4 years ago

Hi, I have same problem, and found the way to resolve it.

In my Code...

// AComponent.tsx
...
export const { dispatch, useGlobalState } = createStore(reducer, initialState);
// BComponent.tsx
import { useGlobalState } from './AComponent';

...
{
  const [test, setTest] = useGlobalState('test')
}

So, my solution is like that, mock that import module

const initialState: MyState = {
    test: {}
};
const { setGlobalState, useGlobalState } = createGlobalState(initialState);

jest.mock('./AComponent', () => {
    return {
        useGlobalState: jest.fn().mockImplementation((args) => useGlobalState(args))
    };
})

within the test code, we can modify that state with setGlobalState

...
test('test', () => {
...
  setGlobalState('test', {value: true});
  const wrapper = mount(<BComponent>);
  // then check the component itself.

I want this will help you, @k-patton

dai-shi commented 2 years ago

v2 is released and closing this.