簡體   English   中英

測試Redux登錄操作

[英]Testing a Redux login Action

我希望我能就如何測試涉及登錄API調用的Redux Action尋求幫助。 我已經看過一些測試異步Action的例子,但是我還沒有考慮如何測試下面的代碼。

作為一個起點,我想測試a)如果.post請求返回200 and b) localStorage`包含來自API調用的令牌,則調用AUTH_USER

我已經看過使用redux-mock-storefetch-mockisomorphic-fetch來模擬API調用以確保我總是收到預期的API響應,但我不知道從哪里開始測試。

任何幫助都將在測試的起點上受到高度贊賞! 甚至一些幫助只是測試200將返回AUTH_USER將不勝感激!

注意:其他我正在使用的測試,redux-mock-store,酶,chai,expect,fetch-mock,isomorphic-fetch

import axios from 'axios';
import { browserHistory } from 'react-router';
import { API_URL } from 'config';
import {
  AUTH_USER
} from './types';

export function loginUser({ email, password }) {
  return function (dispatch) {
    axios.post(`${API_URL}/auth/login`, { email, password })
      .then((response) => {
        dispatch({ type: AUTH_USER });
        localStorage.setItem('token', response.data.token);
        browserHistory.push('/feature');
      })
      .catch(() => {
        dispatch(authError('Bad Login Info'));
      });
  };
}

異步測試動機

我們希望確保如果登錄失敗,如果登錄成功AUTHENTICATION_FAILED操作,則我們的redux thunk中間件將調度AUTHENTICATION_SUCCESS操作。

請記住,我們不是在測試Redux Thunk中間件,而只是測試我們的Thunk Action創建者。

測試查詢API的Redux Thunk動作創建者

  1. 使用redux-thunk中間件為每個單元測試創​​建一個模擬存儲
  2. 使用模擬庫(如nock)攔截http請求以測試為給定類型的請求調度哪些操作。 由於我們正在測試登錄請求,因此這里的明顯案例是http響應,表示登錄成功和失敗。
  3. 驗證是否已針對給定的http響應將正確的操作分派給商店。

測試

下面是使用nock模擬api調用和expect庫以進行測試斷言的兩次登錄成功和失敗測試的示例。

import configureMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'
import nock from 'nock'
import expect from 'expect' // You can use any testing library

// modify these imports to suit your project
import * as actions from '../../actions/TodoActions' 
import * as types from '../../constants/ActionTypes'

import {
  AUTH_USER, AUTH_ERROR
} from './types';

const API_URL = 'www.api-example.com'
const middlewares = [ thunk ]
const mockStore = configureMockStore(middlewares)

describe('async actions', () => {
  afterEach(() => {
    nock.cleanAll()
  })

  it('creates AUTH_USER action when user is logged in', () => {
    nock(API_URL)
      .post(/auth/login)
      .reply(200, { data: 'Logged in successfully'] }})

    const expectedActions = [
      { type: AUTH_USER }
    ]
    const store = mockStore({ })

    return store.dispatch(actions.loginUser({'example@x.com','password'}))
      .then(() => { // return of async actions
        expect(store.getActions()).toEqual(expectedActions)
      })
  })

  it('creates AUTH_ERROR if user login fails', () => {
    nock(API_URL)
      .post(/auth/login)
      .reply(404, { data: {error: 404 }] }})

    const expectedActions = [
      { type: AUTH_ERROR }
    ]
    const store = mockStore({ })

    return store.dispatch(actions.loginUser({'example@x.com','password'}))
      .then(() => { // return of async actions
        expect(store.getActions()).toEqual(expectedActions)
      })
  })
})

現在要使示例工作,您需要在thunk動作創建者返回的函數內添加一個return語句。

通過最終返回axios.post給我們的承諾,我們可以在我們的測試中添加.then調用,以便在promise解決調用已分派的操作。

Thunk行動創造者

import axios from 'axios';
import { browserHistory } from 'react-router';
import { API_URL } from 'config';
import {
  AUTH_USER
} from './types';

export function loginUser({ email, password }) {
  return function (dispatch) {
    return axios.post(`${API_URL}/auth/login`, { email, password })
      .then((response) => {
        dispatch({ type: AUTH_USER });
        localStorage.setItem('token', response.data.token);
        browserHistory.push('/feature');
      })
      .catch(() => {
        dispatch(authError('Bad Login Info'));
      });
  };
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM