使用Jest在Redux中测试异步动作创建者(使用axios) [英] Testing async action creator (using axios) in Redux with Jest

查看:90
本文介绍了使用Jest在Redux中测试异步动作创建者(使用axios)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Redux中为异步操作创建者创建测试时遇到问题.我正在使用axios进行获取,并使用Jest进行测试.数据已正确加载到应用程序本身中.只是我正在编写的测试出错了...

I have an issue creating a test for my async action creator in Redux. I am using axios for fetching and Jest for testing. Data is loaded correctly in the app itself. Just the test which I am writing is going all wrong ...

我遵循了有关测试的Redux文档,但是在那里使用了fetchMock.我无法将其转移到我的案件中.

I followed Redux documentation concerning testing, but it is fetchMock used there. I have trouble transferring it to my case.

我尝试了两种均失败的方法:

I tried two approaches which are both failing:

  1. 使用moxios模拟axios
  2. 使用jest.mock('axios')
  1. using moxios to mock axios
  2. using jest.mock('axios'),

这是我的动作创建者中的代码:

This is the code in my action creator:

import {
    BG_LOAD_START, 
    BG_LOAD_SUCCESS, 
    BG_LOAD_FAILURE} from './types'

import axios from 'axios'

export const bgLoad = (url, pictureNumber=0) => {
    return dispatch => {
        dispatch(bgLoadStart());

        return axios.get(url, {
            headers: {
                Authorization: `Bearer ${process.env.REACT_APP_API_KEY}`
            }
        })
            .then(res => dispatch(bgLoadSuccess(res.data.photos[pictureNumber], res.data.name, res.data.url)))
            .catch(err => dispatch(bgLoadFailure(err)))
    }
}

const bgLoadStart = () => {
    return {
        type: BG_LOAD_START
    }
}

const bgLoadSuccess = (bgImage, name, url) => {
    return {
        type: BG_LOAD_SUCCESS,
        payload: {
            bgImage,
            name,
            url
        }
    }
}

const bgLoadFailure = error => {
    return {
        type: BG_LOAD_FAILURE,
        payload: {
            ...error
        }
    }
}

这就是我要测试的内容:

and here is what I have in my test:

import configureStore from 'redux-mock-store'
import thunk from 'redux-thunk'
import {BG_LOAD_START, BG_LOAD_SUCCESS} from '../types'
import {bgLoad} from '../bgLoad'
import moxios from 'moxios'

const middlewares = [thunk];
const mockStore = configureStore(middlewares);
// jest.mock('axios');

describe(`async bgLoad action`, ()=> {

        beforeEach(()=>{
            moxios.install()
        })

        afterEach(()=>{
            moxios.uninstall()
        })

        it(`creates BG_LOAD_SUCCESS when data has been fetched`, ()=> {
        const fetchedData = [{
            image: 'this is example image',
            name: 'my name is image',
            url: 'this is example link'
        }]

        moxios.wait(()=>{
            const request = moxios.requests.mostRecent();
            request.respondWith({
                status: 200,
                response: fetchedData
            })
        })
        // axios.get.mockResolvedValue(fetchedData);

        const expectedActions = [
            {type: BG_LOAD_START},
            {type: BG_LOAD_SUCCESS,
                payload: {
                    bgImage: fetchedData[0].image,
                    name: fetchedData[0].name,
                    url: fetchedData[0].url,
                }
            }
        ]

        const store = mockStore({});

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

这是我从控制台获得的响应:

Here is the response with which I am getting from the console:

Expected value to equal:
      [{"type": "BG_LOAD_START"}, {"payload": {"bgImage": "this is example image", "name": "my name is image", "url": "this is example link"}, "type": "BG_LOAD_SUCCESS"}]
    Received:
      [{"type": "BG_LOAD_START"}, {"payload": {}, "type": "BG_LOAD_FAILURE"}]

推荐答案

以下是使用jest.mock的解决方案:

Here is the solution use jest.mock:

actionCreators.ts:

import { BG_LOAD_START, BG_LOAD_SUCCESS, BG_LOAD_FAILURE } from './types';
import axios from 'axios';

export const bgLoad = (url, pictureNumber = 0) => {
  return dispatch => {
    dispatch(bgLoadStart());

    return axios
      .get(url, {
        headers: {
          Authorization: `Bearer ${process.env.REACT_APP_API_KEY}`
        }
      })
      .then(res => dispatch(bgLoadSuccess(res.data.photos[pictureNumber], res.data.name, res.data.url)))
      .catch(err => dispatch(bgLoadFailure(err)));
  };
};

const bgLoadStart = () => {
  return {
    type: BG_LOAD_START
  };
};

const bgLoadSuccess = (bgImage, name, url) => {
  return {
    type: BG_LOAD_SUCCESS,
    payload: {
      bgImage,
      name,
      url
    }
  };
};

const bgLoadFailure = error => {
  return {
    type: BG_LOAD_FAILURE,
    payload: {
      ...error
    }
  };
};

actionCreators.spec.ts:

import configureStore from 'redux-mock-store';
import thunk, { ThunkDispatch } from 'redux-thunk';
import axios from 'axios';
import { BG_LOAD_START, BG_LOAD_SUCCESS } from './types';
import { bgLoad } from './actionCreators';
import { AnyAction } from 'redux';

const middlewares = [thunk];
const mockStore = configureStore<any, ThunkDispatch<{}, any, AnyAction>>(middlewares);

jest.mock('axios', () => {
  return {
    get: jest.fn()
  };
});

describe(`async bgLoad action`, () => {
  const fetchedData = [
    {
      image: 'this is example image',
      name: 'my name is image',
      url: 'this is example link'
    }
  ];
  afterEach(() => {
    jest.resetAllMocks();
  });

  it(`creates BG_LOAD_SUCCESS when data has been fetched`, () => {
    (axios.get as jest.MockedFunction<typeof axios.get>).mockResolvedValueOnce({
      data: { photos: [fetchedData[0].image], name: fetchedData[0].name, url: fetchedData[0].url }
    });

    const expectedActions = [
      { type: BG_LOAD_START },
      {
        type: BG_LOAD_SUCCESS,
        payload: {
          bgImage: fetchedData[0].image,
          name: fetchedData[0].name,
          url: fetchedData[0].url
        }
      }
    ];

    const store = mockStore({});

    return store.dispatch(bgLoad('https://github.com/mrdulin')).then(() => {
      expect(store.getActions()).toEqual(expectedActions);
      expect(axios.get).toBeCalledWith('https://github.com/mrdulin', {
        headers: {
          Authorization: `Bearer ${process.env.REACT_APP_API_KEY}`
        }
      });
    });
  });
});

带有覆盖率报告的单元测试结果:

Unit test result with coverage report:

 PASS  src/stackoverflow/55966274/actionCreators.spec.ts
  async bgLoad action
    ✓ creates BG_LOAD_SUCCESS when data has been fetched (20ms)

-------------------|----------|----------|----------|----------|-------------------|
File               |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-------------------|----------|----------|----------|----------|-------------------|
All files          |    88.89 |       50 |    71.43 |    88.24 |                   |
 actionCreators.ts |    86.67 |       50 |    71.43 |    85.71 |             15,37 |
 types.ts          |      100 |      100 |      100 |      100 |                   |
-------------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        4.774s, estimated 6s

这是完整的演示: https://github .com/mrdulin/jest-codelab/tree/master/src/stackoverflow/55966274

这篇关于使用Jest在Redux中测试异步动作创建者(使用axios)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆