酶shallowWrapper.setState不适用于redux连接组件

时间:2018-04-04 09:08:13

标签: reactjs redux react-redux jestjs enzyme

在将其标记为重复之前,请仔细阅读

所以,我完成了所有建议的问题,并做了近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连接组件的更改,那么请让我知道你的方法。

3 个答案:

答案 0 :(得分:1)

这是不好的做法。您应该独立测试response.contentSignIn

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 answerthis Enzyme issue