question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Better support unit-testing of reducers that handle lifecycle actions

See original GitHub issue

Context

Using createAsyncThunk, I created a thunk fetchDatato fetch data from the network. I unit-test the (non-trivial) thunk logic and the lifecycle reducers seperately, that is, I have unit tests to

  • Check if the thunk dispatches the right actions, and
  • Check if the reducers update the store correctly for each of the three lifecycle actions.

Problem

To test the reducer logic for any of the lifecycle actions, say the fulfilled action, I need to dispatch the action. I see three options to create the action, none of which seems ideal:

  1. One option is to call fetchData.fulfilled. However, the action creator’s parameters are not explained anywhere in the official docs, and the number of parameters was silently changed in release 1.5.0. This suggests that the action creator is not intended to be called from outside of RTK.
  2. Instead, I could easily write my own action creator of course. However, I guess it would be better if RTK provided it as it would likely be beneficial for many RTK users. After all, unit-testing reducers is quite a common use case 😃
  3. A third option is to mock the data fetching to have the thunk dispatch the lifecycle actions. This is not optimal either because unit-testing reducers should be independent of thunks.

TLDR

I think it would be best if the three lifecycle action creators exposed by a thunk would be an official part of RTK’s API.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:5
  • Comments:12 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
lukasgebhardcommented, Feb 11, 2021

For the meantime, I chose option (2), that is, I wrote action creators to mock the lifecycle actions:

export function mockPendingAction<ThunkArg>(
  typePrefix: string,
  thunkArg: ThunkArg
): PendingAction<ThunkArg> {
  return {
    type: typePrefix + '/pending',
    payload: undefined,
    meta: {
      requestId: '0',
      arg: thunkArg,
      requestStatus: 'pending'
    }
  }
}
export function mockFulfilledAction<PromiseResult, ThunkArg>(
  typePrefix: string,
  promiseResult: PromiseResult,
  thunkArg: ThunkArg
): FulfilledAction<ThunkArg, PromiseResult> {
  return {
    type: typePrefix + '/fulfilled',
    payload: promiseResult,
    meta: {
      requestId: '0',
      arg: thunkArg,
      requestStatus: 'fulfilled'
    }
  }
}
export function mockRejectedAction<ThunkArg>(
  typePrefix: string,
  error: SerializedError,
  thunkArg: ThunkArg
): RejectedAction<ThunkArg> {
  return {
    type: typePrefix + '/rejected',
    payload: undefined,
    error: error,
    meta: {
      requestId: '0',
      arg: thunkArg,
      aborted: false,
      condition: false,
      requestStatus: 'rejected',
      rejectedWithValue: false
    }
  }
}
export function mockRejectedWithValueAction<ThunkArg, RejectedValue>(
  typePrefix: string,
  rejectedValue: RejectedValue,
  thunkArg: ThunkArg
): RejectedWithValueAction<ThunkArg, RejectedValue> {
  return {
    type: typePrefix + '/rejected',
    payload: rejectedValue,
    error: { message: 'Rejected' },
    meta: {
      requestId: '0',
      arg: thunkArg,
      aborted: false,
      condition: false,
      requestStatus: 'rejected',
      rejectedWithValue: true
    }
  }
}

However, this requires redefining the action types (PendingAction, FulfilledAction, RejectedAction, RejectedWithValueAction). Would you mind exporting these types to avoid the need for redefining them?

0reactions
markeriksoncommented, Jun 7, 2021

Resolved in #1083 .

Read more comments on GitHub >

github_iconTop Results From Across the Web

Best practices for unit testing with a React/Redux approach
Best practices for unit testing with a React/Redux approach · Actions & Async Action Creators · Reducers · Components · Connected Components ·...
Read more >
Writing Tests | Redux
Reducers are pure functions that return the new state after applying the action to the previous state. In the majority of cases, the...
Read more >
A nice way to test redux reducers and actions - part I
We'll explore some different options by testing a simple redux reducer. The reducer in question is responsible for managing a list of todos....
Read more >
A better approach for testing your Redux code
Unit tests should interact with it as a whole. There is no point in testing reducers, action creators and selectors in isolation.
Read more >
Redux ToolKit: is it possible to dispatch other actions from the ...
First of all: please note that reducers always need to be pure functions without side effects. So you can never dispatch anything there, ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found