mirror of
https://github.com/pmndrs/zustand.git
synced 2025-12-08 19:45:52 +00:00
* docs: Fix Jest example's usage of default imports Default exports and imports are deprecated. The default import of `zustand` generates a deprecation warning on the console. The default export that was suggested previously would actually fail to compile. See the comments at the very bottom of #559 for further discussion. This commit fixes the example in the documentation by introducing named exports & imports instead of default exports & imports. * docs: Suggest using plain import for Jest `jest.requireActual` is not necessary when we're not mocking any other part of `zustand`. * docs: Fix TypeScript example The `create` function was curried where it should not have been. The example is now written in plain TypeScript, as the code that it contains does not require JSX. * Prettier suggestions * Use `jest.requireActual` to avoid circular dependencies
103 lines
3.6 KiB
Plaintext
103 lines
3.6 KiB
Plaintext
---
|
|
title: Testing
|
|
description: How to test your new store
|
|
nav: 9
|
|
---
|
|
|
|
## Resetting state between tests in **react-dom**
|
|
|
|
When running tests, the stores are not automatically reset before each test run.
|
|
|
|
Thus, there can be cases where the state of one test can affect another. To make sure all tests run with a pristine store state, you can mock `zustand` during testing and use the following code to create your store:
|
|
|
|
```jsx
|
|
import { create as actualCreate } from 'zustand'
|
|
// const { create: actualCreate } = jest.requireActual('zustand') // if using jest
|
|
import { act } from 'react-dom/test-utils'
|
|
|
|
// a variable to hold reset functions for all stores declared in the app
|
|
const storeResetFns = new Set()
|
|
|
|
// when creating a store, we get its initial state, create a reset function and add it in the set
|
|
export const create = (createState) => {
|
|
const store = actualCreate(createState)
|
|
const initialState = store.getState()
|
|
storeResetFns.add(() => store.setState(initialState, true))
|
|
return store
|
|
}
|
|
|
|
// Reset all stores after each test run
|
|
beforeEach(() => {
|
|
act(() => storeResetFns.forEach((resetFn) => resetFn()))
|
|
})
|
|
```
|
|
|
|
The way you mock a dependency depends on your test runner/library.
|
|
|
|
In [jest](https://jestjs.io/), you can create a `__mocks__/zustand.js` and place the code in that file. If your app is using `zustand/vanilla` instead of `zustand`, then you'll have to place the above code in `__mocks__/zustand/vanilla.js`.
|
|
|
|
### TypeScript usage
|
|
|
|
If you are using zustand, as documented in [TypeScript Guide](./typescript.md), use the following code:
|
|
|
|
```typescript
|
|
import { create as actualCreate, StateCreator } from 'zustand'
|
|
// if using Jest:
|
|
// import { StateCreator } from 'zustand';
|
|
// const { create: actualCreate } = jest.requireActual<typeof import('zustand')>('zustand');
|
|
import { act } from 'react-dom/test-utils'
|
|
|
|
// a variable to hold reset functions for all stores declared in the app
|
|
const storeResetFns = new Set<() => void>()
|
|
|
|
// when creating a store, we get its initial state, create a reset function and add it in the set
|
|
export const create = <S>(createState: StateCreator<S>) => {
|
|
const store = actualCreate(createState)
|
|
const initialState = store.getState()
|
|
storeResetFns.add(() => store.setState(initialState, true))
|
|
return store
|
|
}
|
|
|
|
// Reset all stores after each test run
|
|
beforeEach(() => {
|
|
act(() => storeResetFns.forEach((resetFn) => resetFn()))
|
|
})
|
|
```
|
|
|
|
## Resetting state between tests in **react-native** and **jest**
|
|
|
|
You should use the following code in the `__mocks__/zustand.js` file (the `__mocks__` directory should be adjacent to node_modules, placed in the same folder as node_modules, unless you configured roots to point to a folder other than the project root [jest docs: mocking node modules](https://jestjs.io/docs/manual-mocks#mocking-node-modules)):
|
|
|
|
```js
|
|
import { act } from '@testing-library/react-native'
|
|
const { create: actualCreate } = jest.requireActual('zustand')
|
|
|
|
// a variable to hold reset functions for all stores declared in the app
|
|
const storeResetFns = new Set()
|
|
|
|
// when creating a store, we get its initial state, create a reset function and add it in the set
|
|
export const create = (createState) => {
|
|
const store = actualCreate(createState)
|
|
const initialState = store.getState()
|
|
storeResetFns.add(() => {
|
|
store.setState(initialState, true)
|
|
})
|
|
return store
|
|
}
|
|
|
|
// Reset all stores after each test run
|
|
beforeEach(async () => {
|
|
await act(() =>
|
|
storeResetFns.forEach((resetFn) => {
|
|
resetFn()
|
|
})
|
|
)
|
|
})
|
|
```
|
|
|
|
If the `jest.config.js` has `automock: false`, then you need to do the following in `jest.setup.js`:
|
|
|
|
```js
|
|
jest.mock('zustand')
|
|
```
|