0Pricing
React Academy · Lesson

Zustand DevTools & Testing Stores

Connect to Redux DevTools via devtools middleware and unit-test store actions directly.

Zustand DevTools & Testing Stores is a free React Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the React Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Welcome

In this lesson you will connect a Zustand store to Redux DevTools for time-travel debugging and write unit tests for store actions directly.

The devtools Middleware

Wrap your store with the devtools middleware to connect it to the Redux DevTools browser extension. You can then inspect every action and state change in the DevTools timeline.
import { create } from 'zustand';
import { devtools } from 'zustand/middleware';

const useStore = create(
  devtools(
    (set) => ({
      count: 0,
      increment: () => set(s => ({ count: s.count + 1 }), false, 'increment'),
    }),
    { name: 'CounterStore' }
  )
);

Named Actions in DevTools

Pass an action name as the third argument to set() (when using devtools). This label appears in the DevTools timeline, making it easy to trace what changed.
set(s => ({ count: s.count + 1 }), false, 'counter/increment');
// Appears as 'counter/increment' in Redux DevTools

Combining persist and devtools

Chain multiple middlewares. Wrap devtools inside persist to see all state changes including those from storage rehydration.
const useStore = create(
  devtools(
    persist(
      (set) => ({ /* ... */ }),
      { name: 'my-store' }
    ),
    { name: 'MyStore' }
  )
);

Testing Zustand Stores

Zustand stores are plain JavaScript. You can test them directly without rendering any React components. Import the store and call getState() and setState() in your tests.
import { useCounterStore } from './store';

beforeEach(() => useCounterStore.setState({ count: 0 }));

test('increment increases count', () => {
  useCounterStore.getState().increment();
  expect(useCounterStore.getState().count).toBe(1);
});

Resetting State Between Tests

Call setState with the initial values in a beforeEach to reset the store between tests, preventing state leakage between test cases.
const initialState = { count: 0, user: null };

beforeEach(() => {
  useMyStore.setState(initialState);
});

Mocking the Store in Component Tests

For component tests, mock the store hook to return controlled values. This lets you test how the component renders for different store states without actual store logic.
vi.mock('./useCounterStore', () => ({
  useCounterStore: vi.fn(() => ({ count: 5, increment: vi.fn() })),
}));

Testing Async Actions

Mock fetch in your test and call the async action via getState(). Wait for the async operation with await and then assert on the updated state.
global.fetch = vi.fn().mockResolvedValue({
  json: () => Promise.resolve({ id: 1, name: 'Alice' }),
});

await useUserStore.getState().fetchUser(1);
expect(useUserStore.getState().user.name).toBe('Alice');

Production DevTools Guard

Disable devtools in production by conditionally applying the middleware. This prevents exposing your store structure to users.
const isDev = process.env.NODE_ENV === 'development';

const useStore = create(
  isDev ? devtools(storeCreator, { name: 'App' }) : storeCreator
);

Logging Middleware

You can write a custom logging middleware to log every state change to the console — useful when you cannot install browser extensions.
const log = (fn) => (set, get, api) => fn(
  (args, replace, name) => {
    console.log('action', name, args);
    set(args, replace, name);
  }, get, api
);

Quick Check

How do you reset a Zustand store to its initial state between tests?

Recap

Add the devtools middleware and name your actions for readable DevTools timelines. Test stores directly with getState()/setState() without rendering components. Reset state in beforeEach to isolate tests.

Course Complete

Congratulations! You finished **State Management with Zustand**. You can create stores, use selectors, persist state, debug with DevTools, and write unit tests for your store logic.

Frequently asked questions

Is the “Zustand DevTools & Testing Stores” lesson free?

Yes — the full text of “Zustand DevTools & Testing Stores” is free to read here on the web, and the React Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the React Academy course, upgrade to CoddyKit PRO.

What will I learn in “Zustand DevTools & Testing Stores”?

Connect to Redux DevTools via devtools middleware and unit-test store actions directly. You practise React Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start React Academy?

No prior experience is required. React Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Zustand DevTools & Testing Stores” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this React Academy lesson?

Yes. Every React Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Creating Your First Zustand Store
  2. Selectors & Preventing Unnecessary Re-renders
  3. Persisting State with the Persist Middleware
  4. Zustand DevTools & Testing Stores
← Back to React Academy