我已经实现了一个组件(用于打字训练应用程序),它像这样在全局范围内跟踪按键:
class TrainerApp extends React.Component {
constructor() {
// ...
this.handlePress = this.handlePress.bind(this);
}
handlePress(event) {
const pressedKey = event.key;
const task = this.state.task;
const expectedKey = task.line[task.position];
const pressedCorrectly = pressedKey == expectedKey;
this.setState(prevState => {
const newPosition = prevState.task.position +
(pressedCorrectly ? 1 : 0);
return {
// ...prevState, not needed: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-are-merged
task: {
...prevState.task,
position: newPosition,
mistakeAtCurrentPosition: !pressedCorrectly
}
}
})
}
componentDidMount() {
document.addEventListener(this.keyEventTypeToHandle,this.handlePress);
}
componentWillUnmount () {
document.removeEventListener(this.keyEventTypeToHandle,this.handlePress);
}
...
}
而且我想使用 Jest 编写一些单元测试。我最初的想法是:
describe('TrainerApp.handlePress should',() => {
test('move to the next char on correct press',() => {
const app = new TrainerApp();
app.state.task.line = 'abc';
app.state.task.position = 0;
const fakeEvent = { key: 'a' };
app.handlePress(fakeEvent);
expect(app.state.task.position).toBe(1);
});
...
});
但问题是 app.handlePress
依赖于 this.setState
的使用,当组件尚未安装时它未定义。当然,我可以像这样修改 app
:
test('move to the next char on correct press',() => {
const app = new TrainerApp();
app.setState = jest.fn(function(handler) {
this.state = handler(this.state);
});
app.state.task.line = 'abc';
app.state.task.position = 0;
const fakeEvent = { key: 'a' };
app.handlePress(fakeEvent);
expect(app.state.task.position).toBe(1);
});
甚至像这样:
class ExplorableTrainerApp extends TrainerApp {
setState(handler) {
this.state = handler(this.state);
}
}
test('move to the next char on correct press',() => {
const app = new ExplorableTrainerApp();
app.state.task.line = 'abc';
app.state.task.position = 0;
const fakeEvent = { key: 'a' };
app.handlePress(fakeEvent);
expect(app.state.task.position).toBe(1);
});
但这似乎是一种非常脆弱的方法(这里我依赖于这样一个事实,即 .setState
是用函数参数调用的,而它可以只用 newState
参数调用,并且因此,我正在测试实现细节,而不仅仅是行为。是否有更可靠的方法来测试它?
最佳答案
有一些用于测试 React 组件的框架,Enzyme和 react-testing-library既受欢迎又得到很好的支持。
关于javascript - 如何测试依赖于 setState 的未挂载 React 组件的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54612375/