reactjs enzyme shallowWrapper.setState不适用于redux连接的组件

7kqas0il  于 2023-04-05  发布在  React
关注(0)|答案(4)|浏览(87)

标记为重复之前请仔细阅读

所以,我经历了所有的建议问题,并做了近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 }
  });
});

因此,通过上面的代码和输出,我推断浅层 Package 器的setState没有正常工作,因为没有实际更新组件的状态。
顺便提一下

**1.**我也尝试过使用wrapper.dive().instance().setState(),因为我在一些问题中看到,要更新示例的状态,这种方式会更好。不起作用。
**2.**我也试过用wrapper.update()和wrapper.dive().update()强制更新shallowed组件,这个也不行。
我的依赖版本

“react”:“16.0.0”,
“天然React”:“0.50.0”,
“React还原”:“^5.0.6”,
“enzyme”:“^3.3.0”,
“enzyme-adapter-react-16”:“^1.1.1”,
“jest”:“21.2.1”,
“React域”:“^16.2.0”
我已经阅读了关于将组件从redux中分离出来单独测试组件的指南。我这样做了,我的测试用例运行良好,但我想知道这种行为是正常的还是错误,如果有人成功地测试了redux连接组件的状态更改以及渲染更改,请让我知道你的方法。

pbgvytdp

pbgvytdp1#

每次使用dive()时,它都会创建一个新的 Package 器,因此所有调用都引用一个新的 Package 器,而不是您更新的 Package 器。相反,您可以尝试以下操作:

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对this Enzyme issue的回答。

2wnc66cl

2wnc66cl2#

这是不好的做法。您应该单独测试SignInConnectedSignIn

**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

sxpgvts3

sxpgvts33#

试试下面的代码。为我工作。

const newWrapper = wrapper.dive();
console.log(newWrapper.state()) // returns { isLoading: false };
newWrapper.setState({
  isLoading: true
});
console.log(newWrapper.state()) // returns { isLoading: true }
d5vmydt9

d5vmydt94#

首先,你已经知道React setState是如何工作的,为什么还要测试它呢?在我看来,最好测试由状态更改本身触发的DOM更改。
对于你的问题,我认为你需要重新声明 Package 器:

component = wrapper.find(Component);
  component.props().onSomeChange();
  wrapper.update();
  
  component = wrapper.find(Component) // redeclare since the component has changed
  expect(assertion);

相关问题