我希望我能就如何测试涉及登录 API 调用的 Redux Action 寻求一些帮助。我看过一些测试异步 Action 的示例,但我还没有想好如何测试下面的代码。
作为起点,我想测试 a) AUTH_USER
如果 .post
请求返回 200 和 b)
localStorage` 包含来自 API 调用的 token 。
我研究过使用 redux-mock-store
、fetch-mock
和 isomorphic-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 操作创建器
- 使用 redux-thunk 中间件为每个单元测试创建一个模拟商店
- 使用 nock 等模拟库拦截 http 请求,以测试针对给定类型的请求分派(dispatch)了哪些操作。由于我们正在测试登录请求,因此这里明显的情况是 http 响应表示登录成功和失败。
- 验证针对给定的 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/