酶 shallowWrapper.setState 不适用于 redux 连接的组件
Posted
技术标签:
【中文标题】酶 shallowWrapper.setState 不适用于 redux 连接的组件【英文标题】:enzyme shallowWrapper.setState not working for redux connected components 【发布时间】:2018-09-13 18:42:34 【问题描述】:请在标记为重复之前阅读
因此,我检查了所有建议的问题,并进行了近 2 天的研究,以找出问题背后的原因。
这是我所拥有的 -
1. 一个名为 SignIn 的组件,具有连接到 redux 存储的一些本地状态。
class SignIn extends React.Component
constructor(props)
super(props);
this.state = isLoading: false ;
render ()
isLoading
? <SomeLoadingComponent />
: <MainSigninComponent />
export default ConnectedSignIn = connect(mapStateToProps)(SignIn);
现在您可以看到 SignIn 的渲染输出随着本地状态的变化而变化,我打算对这两个输出进行快照测试。
于是我写了两个测试用例。
// This one is alright as it test on the default state and renders the actual SigninComponent.
test(`it renders correctly`, () =>
const wrapper = shallow(<ConnectedSignIn ...props />, context: store );
// .dive() because I intend to snapshot my actual SignIn component and not the connect wrapper.
expect(wrapper.dive()).toMatchSnapshot();
);
现在,当我打算将状态更改为 isLoading: true 时,我会在第二次测试中像这样调用 setState。
test(`it renders the loading view on setting isLoading state to true`, () =>
const wrapper = shallow(<ConnectedSignIn ...props />, context: store );
console.log(wrapper.dive().state()) // returns isLoading: false
// Again .dive because I want to call setState on my SignIn component
wrapper.dive().setState( isLoading: true );
console.log(wrapper.dive().state()) // still returns isLoading: false
// Tried the callback method to ensure async op completion
wrapper.dive().setState( isLoading: true , () =>
console.log(wrapper.dive().state()) // still returns isLoading: false
);
);
所以通过上面的代码和输出,我推断浅包装器的 setState 不能正常工作,因为实际上没有更新组件的状态。
顺便提一下,
1. 我也尝试过使用 wrapper.dive().instance().setState() 正如我在某个问题中读到的那样,要更新实例的状态,这种方式会更好。 没用。
2. 我还尝试使用 wrapper.update() 和 wrapper.dive().update() 强制更新浅化组件。这个也不行。
我的依赖版本
“反应”:“16.0.0”,
"react-native": "0.50.0",
"react-redux": "^5.0.6",
“酶”:“^3.3.0”,
"enzyme-adapter-react-16": "^1.1.1",
“开玩笑”:“21.2.1”,
"react-dom": "^16.2.0"
我已经阅读了通过将组件与 redux 分开来单独测试组件的指南。我这样做了,我的测试用例运行良好,但我想知道这种行为是正常的还是错误的,如果有人成功地测试了状态更改以及渲染 redux 连接组件的更改,那么请告诉我你的方法。
【问题讨论】:
奇怪,没人试过。 【参考方案1】:每次您使用dive()
时,它都会创建一个新包装器,因此您的所有调用都引用了一个新包装器,而不是您更新的包装器。相反,你可以试试这个:
test(`it renders the loading view on setting isLoading state to true, () =>
const wrapper = shallow(<ConnectedSignIn ...props />, context: store );
const component = wrapper.dive()
component.setState( isLoading: true );
console.log(component.state()) // should be isLoading: true
);
有关参考,请参阅Jordan Harband's answer 至 this Enzyme issue。
【讨论】:
【参考方案2】:这是不好的做法。您应该独立测试SignIn
和ConnectedSignIn
。
1.创建命名导出。
// SignIn.js
export class SignIn extends React.Component
constructor(props)
super(props);
this.state =
isLoading: false
;
render()
const isLoading = this.state;
return (
(isLoading) ? <SomeLoadingComponent /> : <MainSigninComponent />
);
export default ConnectedSignIn = connect(mapStateToProps)(SignIn);
2. 使用以下语法导入SignIn
组件。
import SignIn from 'SignIn.js'
请注意,我们导入 SignIn
而不是 ConnectedSignIn
。
【讨论】:
我不能同意更多。已经采用了上述做法,但仍然对我的问题中提到的问题的原因感到好奇。【参考方案3】:试试下面的代码。为我工作。
const newWrapper = wrapper.dive();
console.log(newWrapper.state()) // returns isLoading: false ;
newWrapper.setState(
isLoading: true
);
console.log(newWrapper.state()) // returns isLoading: true
【讨论】:
以上是关于酶 shallowWrapper.setState 不适用于 redux 连接的组件的主要内容,如果未能解决你的问题,请参考以下文章