sineverba
sineverba

Reputation: 5172

Issue testing RTK Query: The preloadedState argument passed to createStore has unexpected type of "array"

I'm learning RTK Query.

So, in a test, I have the following error:

The preloadedState argument passed to createStore has unexpected type of "array". Expected argument to be an object with the following keys: "queries", "mutations", "provided", "subscriptions", "config"

This is my test:

test("Can use preloadedState", () => {
    const initialPosts = [
      {
        id: 1,
        body: "Lorem ipsum",
      },
    ];

    // wrap component with custom render function
    renderWithProviders(<GenericList />, {
      preloadedState: {
        postsSlice: initialPosts,
      },
    });

    const loremIpsum = screen.getByText(/lorem ipsum/i);
    expect(loremIpsum).toBeInTheDocument();
  });

I have followed this tutorial https://redux.js.org/usage/writing-tests#preparing-initial-test-state.

This is my test-utils.js file:

import React from 'react'
import { render } from '@testing-library/react'
import { Provider } from 'react-redux'
import { setupStore } from '../../store/index'
import { setupListeners } from '@reduxjs/toolkit/dist/query'

export function renderWithProviders(
  ui,
  {
    preloadedState = {},
    // Automatically create a store instance if no store was passed in
    store = setupStore(preloadedState),
    ...renderOptions
  } = {}
) {

  setupListeners(store.dispatch);

  function Wrapper({ children }) {
    return <Provider store={store}>{children}</Provider>
  }

  return { store, ...render(ui, { wrapper: Wrapper, ...renderOptions }) }
}

This is my store:

import { configureStore } from "@reduxjs/toolkit";
import { postsSlice } from "../features/postsSlice";



export const setupStore = preloadedState => {
  return configureStore({
    reducer: {
      [postsSlice.reducerPath]: postsSlice.reducer,
    },
    preloadedState,
    middleware: getDefaultMiddleware =>
        getDefaultMiddleware({
    immutableCheck: false,
    serializableCheck: false,
  }).concat(postsSlice.middleware),
  })
}

And finally this is the postsSlice

import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";

export const postsSlice = createApi({
    // Reducer Path it's name shown on Redux Tab
    reducerPath: "postsSlice",
    baseQuery: fetchBaseQuery({
        baseUrl: process.env.REACT_APP_BACKEND_URL,
    }),
    // With tag type we can invalidate cache
    tagTypes: ['posts'],
    endpoints: (builder) => ({
        getPosts: builder.query({
            query: () => "/posts"
        })
    })
});

export const { useGetPostsQuery } = postsSlice;

Upvotes: 0

Views: 921

Answers (1)

phry
phry

Reputation: 44236

You cannot just make up some random contents for your initialState, it has to be exactly the structure of your Redux state. And for RTK Query, that is a very complex internal structure that you should probably not mock (it could change in another version!).

Honestly, to your last question, this is a step backwards - if you want to test RTK Query, test it with a normal Redux store and mock the api.
All you were missing was to wait in your test until the result was rendered.
Faking internal data structures means that your test will just test a very small part of what actually happens.

Upvotes: 2

Related Questions