【发布时间】:2017-09-21 00:30:44
【问题描述】:
我正在编写一个 SPA (React) 应用程序,我正在为该应用程序使用 Redux 和 Jest。
现在,在我的 reducer 中,我确实有一个动作,它会在加载所有内容后从屏幕上删除一些初始 HTML(启动屏幕)。这通过window.onload() 事件进行检查。
但是,当我使用 JEST 调用它时,会抛出一个错误,指出 window.onload 不是函数。
如何解决,下面是我的reducer。
export const reduxReducer = (state = initialReducerState, action) => {
switch (action.type) {
case ReduxActions.FADE_OUT_AND_REMOVE_SPLASH_SCREEN:
// Set an event handler to remove the splash screen after the window has been laoded.
// This ensures that all the content is loaded.
window.onload(() => {
document.getElementsByClassName("splash-screen")[0].classList.add("fade-out");
// Set a timeout to remove the splash screen from the DOM as soon as the animation is faded.
setTimeout(() => {
let splashScreenElement = document.getElementsByClassName("splash-screen")[0];
splashScreenElement.parentNode.removeChild(splashScreenElement);
let styleElements = document.getElementsByTagName('style');
for (let i = 0; i < styleElements.length; i++) {
styleElements[i].parentNode.removeChild(styleElements[i]);
}
}, 500);
});
// Returns the updated state.
return {
...state,
appBootstrapped: false
}
default:
return {
...state
};
}
};
当然还有我的测试文件:
it("Update 'appBootstrapped' to true when the 'FADE_OUT_AND_REMOVE_SPLASH_SCREEN' action is invoked.", () => {
// Arrange.
const expectedReduxState = {
appBootstrapped: true
};
// Assert.
expect(reduxReducer(undefined, { type: FADE_OUT_AND_REMOVE_SPLASH_SCREEN })).toEqual(expectedReduxState);
});
【问题讨论】:
-
Reducer 应该是纯函数。这就是为什么你在测试它时遇到问题。来自文档。 “给定相同的参数,它应该计算下一个状态并返回它。没有意外。没有副作用。没有 API 调用。没有突变。只是一个计算”
-
那么修改DOM的逻辑应该放在哪里?
-
嗯,有很多选择。例如中间件或动作创建者。但绝对不是 reducer,因为让 reducer 不是纯粹的会破坏可测试性、可复制性等。
-
感谢您的澄清,我一定会从减速器中删除该功能:-)
标签: javascript reactjs jestjs