在将其标记为重复之前,请仔细阅读
所以,我完成了所有建议的问题,并做了近2天的研究,找出问题背后的原因。
这就是我所拥有的 -
1。名为SignIn的组件,其中一些本地状态已连接到redux store。
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”,
“酶 - 衔接子 - 反应-16”:“^ 1.1.1”,
“jest”:“21.2.1”,
“react-dom”:“^ 16.2.0”
我已经通过将它们与redux分开来阅读有关单独测试组件的指南。我这样做了,我的测试用例运行正常,但我想知道这种行为是正常还是错误,如果有人成功测试状态变化以及渲染redux连接组件的更改,那么请让我知道你的方法。
答案 0 :(得分:1)
这是不好的做法。您应该独立测试response.content
和SignIn
。
1。创建命名导出。
ConnectedSignIn
2. 使用以下语法导入// 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);
组件。
SignIn
请注意,我们导入import { SignIn } from 'SignIn.js'
而不是SignIn
。
答案 1 :(得分:0)
尝试以下代码。为我工作。
const newWrapper = wrapper.dive();
console.log(newWrapper.state()) // returns { isLoading: false };
newWrapper.setState({
isLoading: true
});
console.log(newWrapper.state()) // returns { isLoading: true }
答案 2 :(得分:0)
每次使用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。