我有以下Redux动作创建者:
export const keyDown = key => (dispatch, getState) => {
const { modifier } = getState().data;
dispatch({ type: KEYDOWN, key });
return handle(modifier, key); // Returns true or false
};
以下连接组件:
export const mapDispatchToProps = dispatch => ({
onKeyDown: e => {
if(e.target.tagName === "INPUT") return;
const handledKey = dispatch(keyDown(e.keyCode));
if(handledKey) {
e.preventDefault();
}
}
});
我正在尝试编写测试,以确保当dispatch
不是keyDown
时,使用tagName
操作调用"INPUT"
。这是我的考验:
import { spy } from "sinon";
import keycode from "keycodes";
import { mapDispatchToProps } from "./connected-component";
import { keyDown } from "./actions";
// Creates a simple Event stub...
const createEvent = (tag, keyCode) => ({
target: {
tagName: tag.toUpperCase()
},
preventDefault: spy(),
keyCode
});
it("Dispatches a keyDown event with the specified keyCode if the selected element is not an <input>", () => {
const dispatch = spy();
const keyCode = keycode("u");
mapDispatchToProps(dispatch).onKeyDown(createEvent("div", keyCode));
// This fails...
expect(dispatch).to.have.been.calledWith(keyDown(keycode));
});
据推测,这与使用箭头功能有关吗?有什么方法可以确保使用我期望的函数签名调用调度吗?
答案 0 :(得分:3)
keyDown(keycode)
每次都会创建一个新函数,并且每个函数实例都不同,测试用例会按预期失败。
这可以通过记忆keyDown
:
let cacheKeyDown = {};
export const keyDown = key => cacheKeyDown[key] || cacheKeyDown[key] = (dispatch, getState) => {
const { modifier } = getState().data;
dispatch({ type: KEYDOWN, key });
return handle(modifier, key);
};
通过记忆,使用相同keyDown
的{{1}}次调用会返回相同的功能。
答案 1 :(得分:3)
最简单的解决方案可能是按照另一个答案(+1)中的建议记住keyDown()
。这是一种尝试涵盖所有基础的不同方法......
自从keyDown()
导入actions
后,我们可以stub
返回的功能
使用dummy
调用时keyCode
值为import * as actions;
keyDown = stub(actions, "keyDown");
keyDown.withArgs(keyCode).returns(dummy);
:
dispatch
然后,我们的unit tests将使用我们之前设置的dummy
来验证dummy
。我们知道keyDown()
只能由我们的存根keyDown()
返回,因此此检查还会验证是否已调用mapDispatchToProps(dispatch).onKeyDown(createEvent("div", keyCode));
expect(dispatch).to.have.been.calledWith(dummy);
expect(keyDown).to.have.been.calledWithExactly(keyCode);
。
<input>
为了彻底,我们应该添加单元测试,以确认当目标是mapDispatchToProps(dispatch).onKeyDown(createEvent("input", keyCode));
expect(dispatch).to.not.have.been.called;
expect(keyDown).to.not.have.been.called;
时,键事件不分派。
keyDown()
我们还应该通过验证使用正确的键事件和键调用给定的dispatch
回调来孤立test expect(dispatch).to.have.been.calledWith({type: actions.KEYDOWN, key: keyCode});
代码:
var refCompaniesById = firebase.database().ref('companies').child(id);
链接
答案 2 :(得分:2)
正如@DarkKnight所说(获得+1),keyDown
正在为每次调用返回一个新函数,因此测试失败,因为keyDown(keyCode)
!= keyDown(keyCode)
。
如果您不想更改keyDown
的实际实现,可以在模拟测试中进行模拟:
import * as actions from "./actions";
spyOn(actions, 'keyDown');
您可以看到有关如何完成的其他答案: