【问题标题】:How to unit test components with react hooks?如何使用反应钩子对组件进行单元测试?
【发布时间】:2019-09-30 14:02:07
【问题描述】:

目前正在尝试使用钩子(useState 和 useEffects)对组件进行单元测试。 正如我所读到的,生命周期只能通过安装而不是浅渲染来测试。

实现代码:

export function MainPageRouter({issuerDeals, match, dbLoadIssuerDeals}) {
console.log("MainPageRouter")
const [isLoading, setIsLoading] = useState(true);


const selectedIssuerId = match.params.id;
const issuerDeal = filterIssuerDealByIssuerId(issuerDeals, 
selectedIssuerId);

useEffect(() => {
   dbLoadIssuerDeals(selectedIssuerId)
     .then(() => {
        setIsLoading(false);
      })
     .catch(function (error) {
        setIsLoading(false);
        });
  }, [selectedIssuerId]);

  if (isLoading) {
    return <MainPageLoading />
  } else if(issuerDeal.length > 0) {
    return <MappedDeal match={match}/>
  } else {
    return <MapDeal match={match}/>
  }

}

const mapStateToProps = state => {
  return {
    deals: state.deals,
    issuerDeals: state.issuerDeals
  }
};

const mapDispatchToProps = {
  dbLoadIssuerDeals
}

export default connect(mapStateToProps, mapDispatchToProps)(MainPageRouter);

但是这样做会导致这个错误:

Warning: An update to MainPageRouter inside a test was not wrapped in 
act(...).

When testing, code that causes React state updates should be wrapped into 
act(...):

act(() => {
  /* fire events that update state */
});

测试:

it('Should render Mapped Deal', () => {
    const dbLoadIssuerDeals = jest.fn(() => Promise.resolve({
        payload:{ deals: { dealid: "1", sourceCode: "TEST" }, issuerId: "1" } }))
    const props = createProps(issuerDeals, dbLoadIssuerDeals);
    const mainPageRouter = mount(<MemoryRouter><MainPageRouter{...props} /></MemoryRouter>);
});

是否有一种干净的方法来测试 mainPageRouter 是否会返回 MappedDeal 或 MapDeal?我也明白使用 mount 更适合集成测试。

【问题讨论】:

  • 这只是一个警告,而不是错误。无论如何,您是否考虑过使用反应测试库而不是酶? blog.logrocket.com/…

标签: javascript unit-testing react-redux enzyme


【解决方案1】:

您收到的警告不是由使用钩子每看到引起的,而是因为您有导致状态更新的副作用

在您的组件初始渲染后发生了一些事情:您正在从 dbLoadIssuerDeals 服务获取数据并更新本地状态,从而导致重新渲染。但是,您的测试在第一次渲染后立即运行,这意味着它无法正确断言效果之后发生的任何事情。您基本上只能测试显示MainPageLoading,但没有其他分支语句。 React 的 act 测试 API 会警告你。

act 中运行您的代码可确保执行状态更新和排队的副作用。换句话说,它让您“等待”状态更新导致的更改。您可以在React's official docs 中阅读有关act 的更多信息。

我建议直接使用 React Testing Library 而不是 Enzyme 或 React DOM 的测试实用程序。它为您在act 中包装了更新和事件,允许您在没有样板的情况下编写更具表现力的测试。

【讨论】:

    猜你喜欢
    • 2019-12-01
    • 2015-12-06
    • 2019-12-09
    • 1970-01-01
    • 2020-09-28
    • 2020-05-15
    • 2020-01-20
    • 1970-01-01
    • 2017-05-02
    相关资源
    最近更新 更多