【问题标题】:Enzyme: How to test props change of a container component?Enzyme:如何测试容器组件的 props 变化?
【发布时间】:2021-08-13 22:17:19
【问题描述】:

为了渲染连接到redux store的容器组件,我使用这个函数来渲染组件

function render(Component, props, storeData) {
  const mockStore = configureStore([thunkMiddleware]);
  const store = mockStore(storeData);

  return mount(
    <Provider store={store}>
      <Component {...props} />
    </Provider>
  );
}

现在,我需要测试渲染组件的道具更改,但看起来ReactWrapper.setProps 仅适用于根组件。
MyComponent 是一个容器组件,它使用connect 连接到存储。

describe('MyComponent', () => {
  it('should work at props change', () => {
    const wrapper = render(MyComponent, { value: 1 }, initialStoreValue);

    wrapper.find(MyComponent).setProps({ value: 2});
    
    // then expect something.
  });
});

【问题讨论】:

  • 当我使用一个使用 Radium 的组件时会发生类似的问题。我必须用 &lt;StyleRoot&gt; 包装组件来安装该组件,因此,我无法更新道具。

标签: reactjs unit-testing redux jestjs enzyme


【解决方案1】:

需要考虑的几件事:

  1. redux-mock-store 允许将函数作为状态源传递 - redux-mock-store 每次都会调用该函数
  2. 要使用useSelectorconnect() 触发重新渲染组件,我们只需dispatch() 使用任何操作类型即可。从字面上看。
  3. 我们需要将更新存储包装到act() 中,否则可能无法正常工作,肯定会向console.error 投诉。

记住这一点,我们可以增强render

function render(Component, props, initialStoreData) {
  let currentStoreData = initialStoreData;
  const mockStore = configureStore([thunkMiddleware]);
  const store = mockStore(() => currentStoreData);

  const wrapper = mount(
    <Provider store={store}>
      <Component {...props} />
    </Provider>
  );
  const updateStore = (newStoreData) => {
    currentStoreData = newStoreData;
    act(() => {
      store.dispatch({ type: '' }); // just to trigger re-rendering components
    });
  }
  return { wrapper, updateStore };
}

然后在测试中:

describe('MyComponent', () => {
  it('does something when store changes somehow', () => {
    const { wrapper, updateStore } = render(MyComponent, { value: 1 }, initialStoreValue);
    
    updateStore({ someReduxValue: 2});

    // then expect something.
  });
});

【讨论】:

  • 但这不会更新给组件的 props,是吗?
  • 我不懂问题。如果被测组件实际上是connect() + 底层组件,那么底层组件会在store更新后得到新的props。并且所有消耗道具的东西都会有所不同(实际上,您最好检查而不是道具更改检测 - 按钮是否隐藏,文本标签是否更改等)
  • 或者你的意思是用这种方法真正的reducers不会跳进去并且触发一个动作不会相应地更新存储?但这就是重点:您只需模拟存储数据,而不是模拟每个 fetch 或其他第 3 方 API 调用。
猜你喜欢
  • 2018-02-07
  • 2020-10-09
  • 2017-06-29
  • 1970-01-01
  • 1970-01-01
  • 2018-11-27
  • 2017-01-01
  • 1970-01-01
  • 2017-05-03
相关资源
最近更新 更多