Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reset zustand state between tests #242

Closed
0xR opened this issue Nov 16, 2020 · 9 comments
Closed

Reset zustand state between tests #242

0xR opened this issue Nov 16, 2020 · 9 comments

Comments

@0xR
Copy link

0xR commented Nov 16, 2020

I like how simple zustand is, however I need to be able to run tests in isolation. Currently tests will fail because the state of the previous test is affecting the next test.

A solution would be a possibility to reset all stores to the initial state or a way to use a Provider to get a new instance of Zustand for every test.

I tried resetting modules in Jest, but that doesn't play well with testing-library. Currently I just added a reset action to my store.

Or is there a better way to test?

I'm using React, Jest and react-testing-library

@dai-shi
Copy link
Member

dai-shi commented Nov 16, 2020

I haven't tried, but does it work?

const savedState = store.getState()
store.setState(savedState, true /* replace */)

@0xR
Copy link
Author

0xR commented Nov 17, 2020

Ah there is a useStore.setState and useStore.getState.

Maybe the usage with testing can be added to the readme.

I'm using this for now:

const initialStoreState = useStore.getState();
describe('MyComponent', () => {
  beforeEach(() => {
    useStore.setState(initialStoreState, true);
  });
...

@3nvi
Copy link
Contributor

3nvi commented Jan 6, 2021

I actually found a pretty nice automatic way of performing store cleanups in a very transparent way (at least in React) without any change in your source or test code.

I've mocked zustand by adding the following code in a __mocks__/zustand.ts file:

import actualCreate from 'zustand';

const stores = new Set<Function>();

const create: typeof actualCreate = createState => {
  const store = actualCreate(createState);
  const initialState = store.getState();
  stores.add(() => store.setState(initialState, true));

  return store;
};

afterEach(() => {
  stores.forEach(resetFn => resetFn());
});

export default create;

The idea is to mock the store creation in order keep a list of all the stores that have been created within the app, get their first/original state and then use it reset them in a jest afterEachhook (can also work with any other teardown hook of any test runner)

@dai-shi I'd be willing to clean it up a bit & make it part of zustand itself (as something optional), if you think that it might be helpful. Alternatively, it could also be added as part of a recipe.

@dai-shi
Copy link
Member

dai-shi commented Jan 6, 2021

@3nvi
It can be either:

  1. zustand/testing
  2. a recipe in readme
  3. a recipe in docs or wiki

I think 2 or 3 seem good for now. Or, won't you create a dedicated issue to discuss and get feedback with others?

@3nvi
Copy link
Contributor

3nvi commented Jan 6, 2021

Sure thing. I can put up a PR for the readme & create an issue illustrating a potential approach for zustand/testing. If it doesn't get enough traction, it can be closed it in a few weeks. How does that sound?

P.S. Regarding (2), I can't seem to find a dedicated docs page and the wiki seems empty. Am I missing something?

@dai-shi
Copy link
Member

dai-shi commented Jan 6, 2021

Sounds great.

I can't seem to find a dedicated docs page and the wiki seems empty. Am I missing something?

That's correct. This would be the first one. The readme is now getting long and it would be a good chance.

@coltanium13
Copy link

coltanium13 commented Aug 9, 2023

Ah there is a useStore.setState and useStore.getState.

Maybe the usage with testing can be added to the readme.

I'm using this for now:

const initialStoreState = useStore.getState();
describe('MyComponent', () => {
  beforeEach(() => {
    useStore.setState(initialStoreState, true);
  });
...

@dai-shi Does this violate the rules of hooks? You are using the useStore in the test, and its outside of a component or another custom hook. However, the rule does no seem to throw any other errors. use using the useStore allowed in tests and other non custom hook helper functions? It seems here, this is not the useStore zustand hook, but just the store returned from the 'create' function. Is that returned store still a hook?

Thank you!

@dai-shi
Copy link
Member

dai-shi commented Aug 9, 2023

useStore.setState(...) is not using the hook.

👉 #1986

@coltanium13
Copy link

@dai-shi this thread can be closed, and we can continue the discussion in
#1986

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants