javascript - 测试 Redux 登录操作

标签 javascript unit-testing testing redux

我希望我能就如何测试涉及登录 API 调用的 Redux Action 寻求一些帮助。我看过一些测试异步 Action 的示例,但我还没有想好如何测试下面的代码。

作为起点,我想测试 a) AUTH_USER 如果 .post 请求返回 200 和 b)localStorage` 包含来自 API 调用的 token 。

我研究过使用 redux-mock-storefetch-mockisomorphic-fetch 来模拟 API 调用以确保我始终收到预期的 API 响应,但我不知道从哪里开始测试。

对于测试的起点,我们将不胜感激!即使只是测试 200 将返回 AUTH_USER 的一些帮助,我们也将不胜感激!

注意:我在其他地方使用的其他测试有 redux-mock-store、enzyme、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'));
      });
  };
}

最佳答案

异步测试动机

如果登录成功,我们希望确保由我们的 redux thunk 中间件发送 AUTHENTICATION_SUCCESS 操作;如果登录失败,则发送 AUTHENTICATION_FAILED 操作。

请记住,我们不是在测试 Redux Thunk 中间件,而只是在测试我们的 Thunk Action 创建器。

测试查询 API 的 Redux Thunk 操作创建器

  1. 使用 redux-thunk 中间件为每个单元测试创​​建一个模拟商店
  2. 使用 nock 等模拟库拦截 http 请求,以测试针对给定类型的请求分派(dispatch)了哪些操作。由于我们正在测试登录请求,因此这里明显的情况是 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 Action 创建者返回的函数中添加一个 return 语句。

通过最终返回 axios.post 给我们的 promise,我们可以在测试中添加 .then 调用,以断言在 promise 解决后 已分派(dispatch)了哪些操作。

Thunk Action 创作者

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'));
      });
  };
}

关于javascript - 测试 Redux 登录操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41221618/

相关文章:

testing - 如何将唯一 ID 添加到自定义单元格?

testing - 注册测试 : how to test "not deny"?

javascript - 在 html 中添加 anchor 标记和潜在的 javascript 干扰问题

java - 如何为 Google Closure 制作插件

javascript - 为什么选中复选框时 DOM 没有更新?

unit-testing - 如何在 Rust 中测试结构的实例化?

javascript - Jquery Datatables 在 json 表中添加新行

java - JUnit:针对不同实现和细粒度结果状态的相同测试

web-services - 我们应该对 Web 服务进行单元测试吗?

c# - 如何重构测试应用?