如何在 redux 工具包中模拟 store

Dor*_*mon 12 reactjs redux react-testing-library

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();
  });
});
Run Code Online (Sandbox Code Playgroud)

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

类型错误:store.getState 不是函数

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

srk*_*srk 11

我假设您正在尝试测试连接的组件,并且您期望 (1) 操作创建者和减速器运行以及 (2) redux 状态作为测试的一部分进行更新?

我没有使用过 redux-mock-store,但我在他们的文档中看到了以下注释,这让我相信这个库可能无法按照您期望的方式工作:

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

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

首先,重写 RTLrender方法:

// 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 }
Run Code Online (Sandbox Code Playgroud)

然后您引用新的渲染方法而不是直接引用 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()
})
Run Code Online (Sandbox Code Playgroud)

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