You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jest与Sinon.JS能否测试React+Redux中的增量getData逻辑?

Testing Incremental Redux Thunk Actions with Jest and Sinon

Great question—this is a common scenario with chained thunk actions, and both Jest and Sinon are fully capable of handling it. Let’s break down why your initial approach falls short, then walk through reliable solutions.

Why Your Initial Approach Fails

Your requests array only includes the first thunk dispatch. The subsequent dispatches (for the second, third batches, etc.) happen inside the first thunk’s promise chain, so they aren’t added to the initial requests array. That’s why Promise.all(requests) only waits for the first batch to finish, leaving later actions unprocessed when you check store.getActions().

Solution 1: Track All Dispatched Thunk Promises

You can monkey-patch your Redux store’s dispatch method to collect every promise returned by thunk dispatches—including those triggered inside the initial thunk’s chain. This ensures you wait for all async work to complete before checking actions:

// Setup: Collect all dispatched thunk promises
let dispatchedPromises = [];
const originalDispatch = store.dispatch;
store.dispatch = (...args) => {
  const result = originalDispatch(...args);
  // Thunks return promises, so we track them
  if (result instanceof Promise) {
    dispatchedPromises.push(result);
  }
  return result;
};

// Trigger the initial thunk
store.dispatch(actions.getData(0, 999));

// Wait for ALL dispatched thunks to resolve
await Promise.all(dispatchedPromises);

// Now you can safely access all actions
const theActions = store.getActions();
// Assert on your actions here (e.g., check for multiple DATA_LOADED actions)

Solution 2: Wait for Expected Actions with waitFor

If you know how many actions should be dispatched in total (or can check for a final "done" action), use Jest’s waitFor (from React Testing Library, or a custom implementation) to wait until the store reflects the complete state:

Using React Testing Library’s waitFor

import { waitFor } from '@testing-library/react';

// Trigger the initial thunk
store.dispatch(actions.getData(0, 999));

// Wait until the expected number of actions are present
await waitFor(() => {
  expect(store.getActions().length).toBe(3); // Adjust to your expected count
});

const theActions = store.getActions();
// Run your assertions

Custom waitFor (if you don’t use React Testing Library)

function waitFor(condition, timeout = 1000) {
  return new Promise((resolve, reject) => {
    const interval = setInterval(() => {
      if (condition()) {
        clearInterval(interval);
        resolve();
      }
    }, 50);
    setTimeout(() => {
      clearInterval(interval);
      reject(new Error('Wait timed out waiting for actions'));
    }, timeout);
  });
}

// Usage:
await waitFor(() => store.getActions().some(action => action.type === 'FETCH_COMPLETE'));

Solution 3: Mock API Calls with Sinon

If you’re using Sinon to stub your API, you can wait for all stubbed calls to resolve. This works well if your thunk chains based on API responses (e.g., hasMore flag):

// Stub the API to return paginated data
const fetchStub = sinon.stub(api, 'fetchData')
  .onFirstCall().resolves({ data: Array(1000), hasMore: true })
  .onSecondCall().resolves({ data: Array(1000), hasMore: false });

// Trigger the initial thunk
store.dispatch(actions.getData(0, 999));

// Wait for all API calls to resolve
await Promise.all(fetchStub.returnValues);

const theActions = store.getActions();
// Assert that the correct actions were dispatched for each batch

About the Manual Dispatch Approach

The manual method you mentioned (adding the second thunk to requests manually) will work for testing individual thunk logic, but it skips testing the critical chaining logic in your production code. That’s the part most likely to break, so it’s better to use one of the above solutions to test the real flow end-to-end.


内容的提问来源于stack exchange,提问作者nonopolarity

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 18:07:51