title: Testing createAsyncThunk Redux Toolkit Jest
body: <p>I am newbee with the redux toolkit library and especially when it comes to testing. I looked through the documentation and read a bunch of posts and articles in regards to this subject but still struggle. I build a simple todo app and included a couple of API requests to cover asynchronous cases. Testing those turned out to be a bit challenging though. I am hoping to get some advice and feedback on my code and what could be improved. I also wanted some opinions on whether testing the createAsyncThunk slice makes sense or not. NOTE: I am not interested in testing the API calls itself, and use mock data to recreate a successful request. </p>
  
  <p>Constructive criticism is very helpful and would be highly appreciated</p>
  
  <p>Please take a look of one of my slice file and test</p>
  
  <p>postsSlice.ts</p>
  
  <pre><code>import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
  import { RootState } from "../../store";
  import axios from "axios";
  
  export type Post = {
    userId: number;
    id: number;
    title: string;
    body: string;
  };
  
  export type PostsState = {
    posts: Post[];
    loading: boolean;
    error: null | string;
  };
  
  export const initalPostState: PostsState = {
    posts: [],
    loading: false,
    error: null,
  };
  
  export const fetchAllPosts = createAsyncThunk(
    "posts/allPosts",
    async (data, { rejectWithValue }) =&gt; {
      try {
        const response = await axios.get(
          `https://jsonplaceholder.typicode.com/posts`
        );
        return (await response.data) as Post[];
      } catch (err) {
        if (!err.response) {
          throw err;
        }
        return rejectWithValue(err.response.data);
      }
    }
  );
  
  export const fetchSuccessful = fetchAllPosts.fulfilled;
  export const fetchPending = fetchAllPosts.pending;
  export const fetchFailed = fetchAllPosts.rejected;
  
  const postsSlice = createSlice({
    name: "Posts",
    initialState: initalPostState,
    reducers: {},
    extraReducers: (builder) =&gt; {
      builder.addCase(fetchSuccessful, (state, { payload }) =&gt; {
        state.posts = payload;
        state.loading = false;
      });
      builder.addCase(fetchPending, (state, action) =&gt; {
        state.loading = true;
      });
      builder.addCase(fetchFailed, (state, action) =&gt; {
        state.error = action.error.message
          ? action.error.message
          : "Failed to load data";
        state.loading = false;
      });
    },
  });
  
  export const selectPosts = (state: RootState) =&gt; state.fetchedPosts;
  export const fetchedPostsReducer = postsSlice.reducer;
  </code></pre>
  
  <p>Testing</p>
  
  <p>postsSlice.test.ts</p>
  
  <pre><code>import {
    initalPostState,
    fetchPending,
    fetchFailed,
    selectPosts,
    fetchSuccessful,
    fetchedPostsReducer,
  } from "./postsSlice";
  import { Post, PostsState } from "./postsSlice";
  import store, { RootState } from "../../store";
  
  const appState = store.getState();
  
  describe("postsSlice", () =&gt; {
    describe("Posts State, Posts Action and Selector", () =&gt; {
      it("should set loading state on true when API call is pending", async (done) =&gt; {
        // Arrange
  
        // Act
        const nextState: PostsState = await fetchedPostsReducer(
          initalPostState,
          fetchPending
        );
        // Assert
        const rootState: RootState = { ...appState, fetchedPosts: nextState };
        expect(selectPosts(rootState).loading).toBeTruthy();
        expect(selectPosts(rootState).error).toBeNull();
        done();
      });
  
      it("should set error state when API call is rejected", async (done) =&gt; {
        // Arrange
        const response = {
          message: "Network request failed",
          name: "error",
        };
        // Act
        const nextState: PostsState = await fetchedPostsReducer(
          initalPostState,
          fetchFailed(response, "")
        );
        // Assert
        const rootState: RootState = { ...appState, fetchedPosts: nextState };
        expect(selectPosts(rootState).loading).toBeFalsy();
        expect(selectPosts(rootState).error).not.toBeNull();
        expect(selectPosts(rootState).error).toEqual("Network request failed");
        done();
      });
  
      it("should update state when API call is successful", async (done) =&gt; {
        // Arrange
        const response: Post[] = [
          {
            userId: 1,
            id: 1,
            title:
              "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
            body:
              "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto",
          },
          {
            userId: 1,
            id: 2,
            title: "qui est esse",
            body:
              "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla",
          },
        ];
        // Act
        const nextState: PostsState = await fetchedPostsReducer(
          initalPostState,
          fetchSuccessful(response, "")
        );
        // Assert
        const rootState: RootState = { ...appState, fetchedPosts: nextState };
        expect(selectPosts(rootState).loading).toBeFalsy();
        expect(selectPosts(rootState).error).toBeNull();
        expect(selectPosts(rootState).posts).toEqual(
          expect.arrayContaining(response)
        );
        done();
      });
    });
  });
  </code></pre>