简体   繁体   English

如何测试依赖setState的已卸载React组件的方法?

[英]How to test an unmounted React component's method that relies on setState?

I have implemented a component (for a typing training app) which tracks key presses on global scope like this: 我已经实现了一个组件(用于打字培训应用程序),该组件可以在全局范围内跟踪按键,如下所示:

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);
    }
    ...
}

and I'd like to write some unit-tests using Jest. 我想用Jest编写一些单元测试。 My initial idea was: 我最初的想法是:

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);
    });
    ...
});

but the problem is app.handlePress relies on usage of this.setState which is not defined when the component is not mounted yet. 但是问题是app.handlePress依赖于app.handlePress用法,当尚未安装组件时, this.setState无法定义this.setState Of'course I can modify the app like this: 当然,我可以这样修改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);
});

or even like this: 甚至像这样:

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);
});

but this seems a very fragile approach (here I rely on the fact that .setState is called with the function argument while it can be called with just newState argument and hence I'm testing implementation details, instead of just the behaviour. Is there a more robust way to test this? 但这似乎是一种非常脆弱的方法(在此我依靠的事实是, .setState是使用函数参数调用的,而它只能使用newState参数调用,因此,我正在测试实现细节,而不仅仅是行为。更强大的方法来测试这一点?

有一些用于测试React组件的框架, Enzymereact-testing-library都很流行并且得到了很好的支持。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 React - 未安装组件上的 setState() - React - setState() on unmounted component 如何避免警告:无法在未安装的组件上设置状态? 反应本机 - How to avoid warning: Cannot setState on unmounted component? REACT-NATIVE React Native:setState +已卸载或正在安装的组件 - React Native: setState + unmounted or mounting component React,setState警告已安装/未安装的组件 - React, setState warning for mounted/unmounted component 如何解决:无法在 React-Native 中的未挂载组件警告上调用 setState(或 forceUpdate)? - How to solve: Can't call setState(or forceUpdate) on an unmounted component warning in React-Native? 反应警告:无法在未安装的组件上调用 setState(或 forceUpdate) - React Warning: Can't call setState (or forceUpdate) on an unmounted component 警告:无法在React Native中的已卸载组件上调用setState(或forceUpdate) - Warning: Can't call setState (or forceUpdate) on an unmounted component in React Native 反应-警告:无法在未安装的组件上调用setState(或forceUpdate) - React - Warning: Can't call setState (or forceUpdate) on an unmounted component 无法在已卸载的组件上调用setState(或forceUpdate)。 应对 - Can't call setState (or forceUpdate) on an unmounted component. React 无法在未安装的组件上设置状态 - can't setState on an unmounted component
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM