测试附加时间戳的 Redux action creator
Testing a Redux action creator that appends a timestamp
针对动作创建者编写 Mocha 测试规范时,我如何确定时间戳是在动作创建者中生成的?
它不一定要使用 Sinon,但我尝试使用 Sinon Fake Timers 到 "freeze time",但由于我有限的存根知识,似乎无法将其拼凑起来和嘲笑。如果这被认为是 Redux 反模式,请指出我更好的方向,但我的理解是 Redux 动作创建者可以是非纯函数,与 reducers 不同。
从Redux Writing Tests Recipes这里借用一点是我理解的问题的核心...
CommonUtils.js
import moment from 'moment';
export const getTimestamp = function () {
return moment().format();
};
TodoActions.js
import { getTimestamp } from '../../utils/CommonUtils';
export function addTodo(text) {
return {
type: 'ADD_TODO',
text,
timestamp: getTimestamp() // <-- This is the new property
};
};
TodoActions.spec.js
import expect from 'expect';
import * as actions from '../../actions/TodoActions';
import * as types from '../../constants/ActionTypes';
import { getTimestamp } from '../../utils/CommonUtils';
describe('actions', () => {
it('should create an action to add a todo', () => {
const text = 'Finish docs';
const timestamp = getTimestamp(); // <-- This will often be off by a few milliseconds
const expectedAction = {
type: types.ADD_TODO,
text,
timestamp
};
expect(actions.addTodo(text)).toEqual(expectedAction);
});
});
我仍然很想看到其他答案,但我终于找到了一个合理的解决方案。此答案使用 proxyquire 到 override/replace getTimestamp() 中定义的方法 CommonUtils 当 使用时测试期间的 TodoActions。
没有对上面的 CommonUtils.js 或 TodoActions.js 进行修改:
TodoActions.spec.js
import expect from 'expect';
import proxyquire from 'proxyquire';
import * as types from '../../constants/ActionTypes';
const now = '2016-01-06T15:30:00-05:00';
const commonStub = {'getTimestamp': () => now};
const actions = proxyquire('../../actions/TodoActions', {
'../../utils/CommonUtils': commonStub
});
describe('actions', () => {
it('should create an action to add a todo', () => {
const text = 'Finish docs';
const timestamp = now; // <-- Use the variable defined above
const expectedAction = {
type: types.ADD_TODO,
text,
timestamp
};
expect(actions.addTodo(text)).toEqual(expectedAction);
});
});
在测试的时候我曾经成功地使用过这个库:https://www.npmjs.com/package/timekeeper
然后在 beforeEach 和 afterEach 中,您可以将时间保存为特定的内容并进行断言,然后将时间重置为正常。
let time;
beforeEach(() => {
time = new Date(1451935054510); // 1/4/16
tk.freeze(time);
});
afterEach(() => {
tk.reset();
});
现在您可以断言返回的时间。这有意义吗?
针对动作创建者编写 Mocha 测试规范时,我如何确定时间戳是在动作创建者中生成的?
它不一定要使用 Sinon,但我尝试使用 Sinon Fake Timers 到 "freeze time",但由于我有限的存根知识,似乎无法将其拼凑起来和嘲笑。如果这被认为是 Redux 反模式,请指出我更好的方向,但我的理解是 Redux 动作创建者可以是非纯函数,与 reducers 不同。
从Redux Writing Tests Recipes这里借用一点是我理解的问题的核心...
CommonUtils.js
import moment from 'moment';
export const getTimestamp = function () {
return moment().format();
};
TodoActions.js
import { getTimestamp } from '../../utils/CommonUtils';
export function addTodo(text) {
return {
type: 'ADD_TODO',
text,
timestamp: getTimestamp() // <-- This is the new property
};
};
TodoActions.spec.js
import expect from 'expect';
import * as actions from '../../actions/TodoActions';
import * as types from '../../constants/ActionTypes';
import { getTimestamp } from '../../utils/CommonUtils';
describe('actions', () => {
it('should create an action to add a todo', () => {
const text = 'Finish docs';
const timestamp = getTimestamp(); // <-- This will often be off by a few milliseconds
const expectedAction = {
type: types.ADD_TODO,
text,
timestamp
};
expect(actions.addTodo(text)).toEqual(expectedAction);
});
});
我仍然很想看到其他答案,但我终于找到了一个合理的解决方案。此答案使用 proxyquire 到 override/replace getTimestamp() 中定义的方法 CommonUtils 当 使用时测试期间的 TodoActions。
没有对上面的 CommonUtils.js 或 TodoActions.js 进行修改:
TodoActions.spec.js
import expect from 'expect';
import proxyquire from 'proxyquire';
import * as types from '../../constants/ActionTypes';
const now = '2016-01-06T15:30:00-05:00';
const commonStub = {'getTimestamp': () => now};
const actions = proxyquire('../../actions/TodoActions', {
'../../utils/CommonUtils': commonStub
});
describe('actions', () => {
it('should create an action to add a todo', () => {
const text = 'Finish docs';
const timestamp = now; // <-- Use the variable defined above
const expectedAction = {
type: types.ADD_TODO,
text,
timestamp
};
expect(actions.addTodo(text)).toEqual(expectedAction);
});
});
在测试的时候我曾经成功地使用过这个库:https://www.npmjs.com/package/timekeeper
然后在 beforeEach 和 afterEach 中,您可以将时间保存为特定的内容并进行断言,然后将时间重置为正常。
let time;
beforeEach(() => {
time = new Date(1451935054510); // 1/4/16
tk.freeze(time);
});
afterEach(() => {
tk.reset();
});
现在您可以断言返回的时间。这有意义吗?