反应组件中的测试方法

testing method within react component

我正在尝试用酶测试反应 class 方法。该方法应该处理输入的变化并设置状态。我收到错误“无法读取未定义的 属性 'setState'

component.js

class LoginPage extends Component {
    constructor(props) {
        super(props);
        this.state = {
            username: '',
            password: ''
        };

        this.handleChange = this.handleChange.bind(this);

        ...
    }

    handleChange(event) {
        this.setState({[event.target.name]: event.target.value})
    }

    ...

    return(
        ...
        <TextField name='username' onChange={this.handleChange} />
    )

test.js

it('handles change', () => {
    const spy = sinon.spy(LoginPage.prototype, 'handleChange');
    const _wrapper = shallow(<LoginPage />);

    spy({
            event: {
                target: {
                    name: 'username',
                    value: 'username'
                }
            }
        }
    );

    expect(_wrapper.state().username).to.equal('username');
})

});

在我回答之前,请注意还有一些其他方法可以编写您的组件,这些方法可以更轻松地编写这些测试(并且更好地使用 spies/stubs)。例如,您可以将 "onChange" 属性传递给组件,然后使用该属性。

所以,回答这个问题,您调用的函数不是 "binded" 任何东西。您的 this(在您创建的间谍中)是 undefined,这就是您出现错误的原因:

Cannot read property 'setState' of undefined

一个简单的解决方法是调用 "binded" 函数:

Just notice that you will need to import "TextField" component, in order to execute "find" correctly

import TextField from '../path/to/TextField.jsx';

it('handles change', () => {
    const _wrapper = shallow(<LoginPage />);

    _wrapper.find(TextField).simulate('change', {
        target: {
            name: 'username',
            value: 'username',
        },
    });

    expect(_wrapper.state().username).to.equal('username');
});

这样,simulate('change') 将使用传递的参数调用 onChange。在这种情况下,onChange 将调用 handleChange,这次 this "binded" 正确。