如何使用 Jest 测试调度的反应函数

时间:2021-02-17 10:21:16

标签: react-redux jestjs react-testing-library

我正在尝试对使用 Axios 帮助程序实例进行异步调用的函数进行单元测试。我尝试了多种尝试对其进行单元测试的方法,但我似乎无法在网上找到任何有帮助的材料。我已经被这个问题困扰了几天,这令人沮丧,所以任何帮助将不胜感激!下面是 Axios Helper 文件(api.js)

api.js

import axios from 'axios'

const API = (token = null) => {
let headers = {
    'Content-Type': 'application/json',
    'Ocp-Apim-Subscription-key': process.env.NEXT_PUBLIC_API_HEADER_SUBSCRIPTION_KEY
}

if (token) {
    const tokenHeader = { Authorization: 'Bearer ' + token }
    headers = { ...headers, ...tokenHeader }
}

const url = process.env.NEXT_PUBLIC_API_BASE_URL

const API = axios.create({
    baseURL: url,
    headers
})

return API
}

export default API

模拟 API

export default {
post: jest.fn(() =>
    Promise.resolve({
        data: {}
    })
),
get: jest.fn(() =>
    Promise.resolve({
        data: {}
    })
)
}

动作文件

export const initiate2FA = (destinationValue) => async () => {
  const twoFactorAuth = destinationValue
  const res = await API().post('/foo', {
      Destination: twoFactorAuth
})

return res
}

Action.test.js

import API from 'api/api'
import { initiate2FA } from 'actions/userActions'

jest.mock('api/api')
const mockedAxios = API
const dispatch = jest.fn()

describe('Initiate2FA function', () => {
  it('bar', async () => {
      mockedAxios.get.mockImplementationOnce(() => Promise.resolve({ status: 200 }))

      const t = await dispatch(initiate2FA('test@test.com'))
      console.log(t)
  })
})

我对上述测试文件的问题是它返回一个匿名函数,我不知道如何处理它以通过单元测试。测试的目标是确保函数被调用。我不确定我是否以正确的方式处理这个问题,还是应该改变我的方法。

同样,任何建议都会很棒!

1 个答案:

答案 0 :(得分:0)

模拟 API 调用是您可以在自己的 React 组件而不是函数上模拟的东西,最好的选择是不在您的组件上模拟任何内容。 Here you can read all about why you should not mock your API functions。在文章的最后,您将找到一个名为 Mock Service Worker 的库,您可以将其用于您的目的。

你声明你有一个需要模拟的实际 HTTP 调用的方式是这样的:

rest.get('/foo', async (req, res, ctx) => {
  const mockedResponse = {bar: ''};
  return res(ctx.json(mockedResponse))
}),

如果你只是需要对一个函数进行单元测试,你仍然可以使用 Mock Service Worker 来解析 HTTP 请求,然后测试之后会发生什么。这仍然是您的首选。测试看起来像:

// this could be in another file or on top of your tests.
rest.get('/foo', async (req, res, ctx) => {
  const mockedResponse = {bar: ''};
  return res(ctx.json(mockedResponse))
}),

// and this would be your test
describe('Initiate2FA function', () => {
  it('bar', async () => {
      const res = await initiate2FA('test@test.com');
      
      expect(res).toBe({bar: '');
  })
})