酶新手在这里。 我试图在调用该组件上的方法后测试是否正在更新React组件的状态。
这是我正在测试的组件的片段:
class App extends React.Component { constructor(props) { super(props); } state = { recipes: {}, user: null }; handleUnauth = () => { this.setState({ user: null }); }; render() { //render children, pass down methods as props etc... } }以下是测试:
import createRouterContext from 'react-router-test-context'; import { shallow, mount } from 'enzyme'; import expect from 'expect'; import React from 'react'; import App from 'App'; //import with webpack alias describe('App', () => { let wrapper, context; beforeEach(() => { context = createRouterContext(); wrapper = mount(<App/>, { context }); }); it('should remove logged in user details on logout', () => { const user = { uid: 'abc123', name: 'John Doe' }; wrapper.setState({ user }, () => { wrapper.instance().handleUnauth(); const userState = wrapper.state('user'); expect(userState).toEqual(null); }); }); });我的测试失败,出现以下错误:
我知道更新状态不是同步的,但我不确定这是否与此有关,或者是否有更好的方法使用Enzyme进行测试。 如果有人能指出我正确的方向,我将非常感激。 哦,我通过在测试中调用wrapper.instance().handleUnauth()之后调用wrapper.instance().handleUnauth()尝试这个,但是这也没有用。
Enzyme newbie here. I am trying to test if the state of a React component is being updated after calling a method on that component.
This is a snippet of the component that I am testing:
class App extends React.Component { constructor(props) { super(props); } state = { recipes: {}, user: null }; handleUnauth = () => { this.setState({ user: null }); }; render() { //render children, pass down methods as props etc... } }Below is the test:
import createRouterContext from 'react-router-test-context'; import { shallow, mount } from 'enzyme'; import expect from 'expect'; import React from 'react'; import App from 'App'; //import with webpack alias describe('App', () => { let wrapper, context; beforeEach(() => { context = createRouterContext(); wrapper = mount(<App/>, { context }); }); it('should remove logged in user details on logout', () => { const user = { uid: 'abc123', name: 'John Doe' }; wrapper.setState({ user }, () => { wrapper.instance().handleUnauth(); const userState = wrapper.state('user'); expect(userState).toEqual(null); }); }); });My test fails with the following error:
I understand that updating of state is not synchronous but I am not sure if that has something to do with this or if there are better ways to test this using Enzyme. Would be super grateful if someone can please point me in the right direction. Oh and I tried this by calling wrapper.update() right after calling wrapper.instance().handleUnauth() in the test but this too didn't work.
最满意答案
从React#setState ,
setState(updater,[callback])
setState()将组件状态的更改排入队列。 setState不会立即更新状态。 setState()并不总是立即更新组件。 它可以批量推迟更新或推迟更新。 这使得在调用setState()之后立即读取this.state是一个潜在的陷阱。相反,使用componentDidUpdate或setState回调(setState(updater, callback))
解决方案1:
从setState删除回调;
wrapper.setState({ user }); wrapper.instance().handleUnauth(); const userState = wrapper.state('user'); expect(userState).toEqual(null);解决方案2:
读取setState callback的callback参数中的更新状态
wrapper.setState({ user }, (userState) => { wrapper.instance().handleUnauth(); //const userState = wrapper.state('user'); // comment it. expect(userState).toEqual(null); });From the React#setState,
setState(updater, [callback])
setState() enqueues changes to the component state. The setState doesn't immediately update the state. setState() does not always immediately update the component. It may batch or defer the update until later. This makes reading this.state right after calling setState() a potential pitfall.Instead, use componentDidUpdate or a setState callback (setState(updater, callback))
Solution 1:
Remove callback from setState;
wrapper.setState({ user }); wrapper.instance().handleUnauth(); const userState = wrapper.state('user'); expect(userState).toEqual(null);Solution 2:
Read the updated state in the callback parameter of setState callback
wrapper.setState({ user }, (userState) => { wrapper.instance().handleUnauth(); //const userState = wrapper.state('user'); // comment it. expect(userState).toEqual(null); });
更多推荐
发布评论