如何使用 Jest 测试 Redux 异步操作?

在前端开发中,Redux 是一个非常流行的状态管理库,它可以让我们更好地管理应用程序的状态。然而,Redux 中的异步操作可能会导致测试变得困难,因为异步操作可能会影响测试的结果。在这篇文章中,我们将介绍如何使用 Jest 测试 Redux 中的异步操作。

前置知识

在本文中,我们假设你已经熟悉 Redux 和 Jest 的基本概念。

安装 Jest

首先,我们需要在项目中安装 Jest。可以使用以下命令:

配置 Jest

接下来,我们需要在项目中添加 Jest 的配置文件。在项目的根目录下创建一个名为 jest.config.js 的文件,并添加以下代码:

module.exports = {
  testEnvironment: 'node',
  setupFilesAfterEnv: ['<rootDir>/setupTests.js'],
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1'
  }
}

这个配置文件告诉 Jest 使用 Node.js 环境运行测试,并且在运行测试之前运行 setupTests.js 文件。还指定了一个模块名称映射,用于将 @ 符号映射到项目中的 src 目录。

编写测试用例

现在,我们可以开始编写测试用例了。我们将使用一个简单的 Redux 异步操作作为示例。假设我们有一个名为 fetchData 的异步操作,它从远程服务器获取数据并将其存储在 Redux store 中。

首先,我们需要编写一个 Redux action,用于触发异步操作。在项目的 src/actions 目录下创建一个名为 dataActions.js 的文件,并添加以下代码:

export const FETCH_DATA_REQUEST = 'FETCH_DATA_REQUEST'
export const FETCH_DATA_SUCCESS = 'FETCH_DATA_SUCCESS'
export const FETCH_DATA_FAILURE = 'FETCH_DATA_FAILURE'

export const fetchDataRequest = () => ({
  type: FETCH_DATA_REQUEST
})

export const fetchDataSuccess = data => ({
  type: FETCH_DATA_SUCCESS,
  payload: data
})

export const fetchDataFailure = error => ({
  type: FETCH_DATA_FAILURE,
  payload: error
})

export const fetchData = () => {
  return async dispatch => {
    dispatch(fetchDataRequest())
    try {
      const response = await fetch('https://api.example.com/data')
      const data = await response.json()
      dispatch(fetchDataSuccess(data))
    } catch (error) {
      dispatch(fetchDataFailure(error))
    }
  }
}

这个文件定义了三个 Redux action:FETCH_DATA_REQUESTFETCH_DATA_SUCCESSFETCH_DATA_FAILURE。还定义了一个 fetchData 异步操作,它将触发 FETCH_DATA_REQUEST action,并从远程服务器获取数据。如果成功,它将触发 FETCH_DATA_SUCCESS action,并将数据作为 payload 存储在 store 中。如果失败,它将触发 FETCH_DATA_FAILURE action,并将错误作为 payload 存储在 store 中。

接下来,我们需要编写一个测试用例来测试这个异步操作。在项目的 src/__tests__ 目录下创建一个名为 dataActions.test.js 的文件,并添加以下代码:

import configureMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'
import fetchMock from 'fetch-mock'
import {
  FETCH_DATA_REQUEST,
  FETCH_DATA_SUCCESS,
  FETCH_DATA_FAILURE,
  fetchData
} from '@/actions/dataActions'

const middlewares = [thunk]
const mockStore = configureMockStore(middlewares)

describe('dataActions', () => {
  afterEach(() => {
    fetchMock.reset()
    fetchMock.restore()
  })

  it('creates FETCH_DATA_SUCCESS when fetching data has been done', () => {
    fetchMock.getOnce('https://api.example.com/data', {
      body: { data: 'test' },
      headers: { 'content-type': 'application/json' }
    })

    const expectedActions = [
      { type: FETCH_DATA_REQUEST },
      { type: FETCH_DATA_SUCCESS, payload: { data: 'test' } }
    ]
    const store = mockStore({ data: {} })

    return store.dispatch(fetchData()).then(() => {
      expect(store.getActions()).toEqual(expectedActions)
    })
  })

  it('creates FETCH_DATA_FAILURE when fetching data has failed', () => {
    fetchMock.getOnce('https://api.example.com/data', {
      status: 404,
      headers: { 'content-type': 'application/json' }
    })

    const expectedActions = [
      { type: FETCH_DATA_REQUEST },
      { type: FETCH_DATA_FAILURE, payload: new Error('Not Found') }
    ]
    const store = mockStore({ data: {} })

    return store.dispatch(fetchData()).then(() => {
      expect(store.getActions()).toEqual(expectedActions)
    })
  })
})

这个测试用例使用了 redux-mock-storeredux-thunkfetch-mock 这三个库来模拟 Redux store、Redux 异步操作和网络请求。它包含两个测试用例:一个测试用例测试异步操作成功的情况,另一个测试用例测试异步操作失败的情况。

运行测试

现在,我们可以运行测试了。在项目的根目录下运行以下命令:

Jest 将运行我们编写的测试用例,并报告测试结果。如果测试通过,我们将看到一个绿色的 PASS 标志;如果测试失败,我们将看到一个红色的 FAIL 标志,并且会显示测试失败的原因。

总结

在本文中,我们介绍了如何使用 Jest 测试 Redux 中的异步操作。我们使用了一个简单的示例来演示如何编写测试用例,并使用 redux-mock-storeredux-thunkfetch-mock 这三个库来模拟 Redux store、Redux 异步操作和网络请求。希望这篇文章对你有所帮助,让你更好地理解如何测试 Redux 异步操作。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/658ccdcbeb4cecbf2d29302d


纠错
反馈