【问题标题】:How to mock store in redux toolkit如何在 redux 工具包中模拟 store
【发布时间】:2021-03-03 15:43:22
【问题描述】:
import React from 'react';
import { Provider } from 'react-redux';
import configureStore from 'redux-mock-store';
import { render, screen, fireEvent } from '@testing-library/react';
import MyApp from './MyApp ';

const initialState = {};
const mockStore = configureStore(initialState);

describe('<MyApp />', () => {
  it('click button and shows modal', () => {
    render(
      <Provider store={mockStore}>
        <MyApp />
      </Provider>
    );

    fireEvent.click(screen.getByText('ADD MIOU'));
    expect(queryByText('Add MIOU Setting')).toBeInTheDocument();
  });
});

我正在使用带有reactjs 的 jest 和 redux 工具包,并尝试模拟商店来编写测试。 但是出现以下错误

TypeError:store.getState 不是函数

有没有办法解决这个问题?我错过了什么吗?

【问题讨论】:

    标签: reactjs redux react-testing-library


    【解决方案1】:

    我假设您正在尝试测试一个连接的组件,并且您希望 (1) 运行动作创建者和缩减程序以及 (2) 作为测试的一部分更新 redux 状态?

    我没有使用过 redux-mock-store,但我在 their documentation 上看到了以下注释,这让我相信这个库可能无法按您预期的方式工作:

    请注意,此库旨在测试与动作相关的逻辑,而不是与减速器相关的逻辑。换句话说,它不会更新 Redux 存储。

    我建议您尝试使用this approach 来测试连接的组件。我已经使用这种方法编写了更新 redux 状态和渲染连接组件的测试。

    首先,覆盖 RTL render 方法:

    // test-utils.js
    import React from 'react'
    import { render as rtlRender } from '@testing-library/react'
    import { createStore } from 'redux'
    import { Provider } from 'react-redux'
    // Import your own reducer
    import reducer from '../reducer'
    
    function render(
      ui,
      {
        initialState,
        store = createStore(reducer, initialState),
        ...renderOptions
      } = {}
    ) {
      function Wrapper({ children }) {
        return <Provider store={store}>{children}</Provider>
      }
      return rtlRender(ui, { wrapper: Wrapper, ...renderOptions })
    }
    
    // re-export everything
    export * from '@testing-library/react'
    // override render method
    export { render }
    

    然后你直接引用新的渲染方法而不是 RTL。您还可以为您的测试提供初始状态。

    import React from 'react'
    // We're using our own custom render function and not RTL's render
    // our custom utils also re-export everything from RTL
    // so we can import fireEvent and screen here as well
    import { render, fireEvent, screen } from '../../test-utils'
    import App from '../../containers/App'
    
    it('Renders the connected app with initialState', () => {
      render(<App />, { initialState: { user: 'Redux User' } })
    
      expect(screen.getByText(/redux user/i)).toBeInTheDocument()
    })
    

    (所有代码复制自redux.js.org。)

    【讨论】:

      【解决方案2】:

      我找不到其他地方可以粘贴我关于 redux 工具包和 redux-mock-store 的发现。

      为了调度异步 thunk 和测试结果,您可以在创建模拟存储时指定调度类型。

      import configureStore from 'redux-mock-store';
      import { getDefaultMiddleware } from '@reduxjs/toolkit'
      
      const middlewares = getDefaultMiddleware();
      const mockStore = createMockStore<IRootState, AppDispatch>(middlewares);
      
      describe('my thunk action', () => {
        const store = mockStore();
      
        test('calls my service', async() => {
          await store.dispatch(myThunk({ id: 32 }));
      
          expect(myService).toBeCalledWith({ id: 32 });
        });
      
        test('contains foo bar actions', async() => {
          await store.dispatch(myThunk({ id: 32 }));
      
          expect(store.getActions()).toEqual(....);
        });
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-22
        • 1970-01-01
        • 1970-01-01
        • 2017-08-30
        相关资源
        最近更新 更多