使用 React Suspense 和 React.lazy 子组件进行 Jest/Enzyme 类组件测试

Posted

技术标签:

【中文标题】使用 React Suspense 和 React.lazy 子组件进行 Jest/Enzyme 类组件测试【英文标题】:Jest/Enzyme Class Component testing with React Suspense and React.lazy child component 【发布时间】:2019-05-15 02:00:14 【问题描述】:

所以我将类组件中使用的导入转换为 React.lazy 导入 api 并将其包装在 Suspense 标记中。当我测试该类组件时,酶会抛出错误"Enzyme Internal Error: unknown node with tag 13"。有没有办法渲染和测试延迟加载组件的挂载,而不是使用浅渲染?

我已经尝试过 async await 来等待延迟加载的承诺得到解决,但这也没有用,就像这样:

it('async await mount', () async () => 
  const wrapper = await mount(<Component />)

这里是示例代码:

组件.js

import React,  PureComponent, Suspense  from 'react'

const ChildComponent = React.lazy(() => import('../ChildComponent'))

export default class Component extends PureComponent 
  constructor() 
      super()
      this.state = 
          example: null
      
  

  doSomething = () => this.setState(
      example: 'example'
  )

  render() 
    return (
      <div>
        <p>Example</p>
        <Suspense fallback=<div>...loading</div>>
            <ChildComponent 
               example=this.state.example
               doSomething=this.doSomething
            />
        </Suspense>
      </div>
    )
  

Component.test.js

import React from 'react'
import renderer from 'react-test-renderer'
import  mount  from 'enzyme'
import Component from '../../Component'

describe('Component', () => 
    // snapshot renders loading and not children
    it('example snapshot of tree', () => 
        const tree = renderer.create(<Component />).toJSON()
        expect(tree).toMatchSnapshot()
    )

    it('example mount test', () => 
        // this test fails and throws error I state above
        const wrapper = mount(<Component />)
        wrapper.setState( example: 'example' )
        expect(wrapper.state.example).toBe('example')
    )
)

我读到 Enzyme 还不支持 React 16.6 Suspense API,但我想知道是否还有一种方法可以测试挂载,以便我可以使用 Enzyme 的 simulatefind API 之类的东西。

【问题讨论】:

这个问题正在Github上讨论github.com/airbnb/enzyme/pull/1975 【参考方案1】:

解决方案

ChuckJHardy 链接的 GitHub 问题已解决合并发布。从 1.14.0 开始,您现在可以在酶中使用 mount API。

参考文献

https://github.com/airbnb/enzyme/pull/1975

【讨论】:

【参考方案2】:

我需要使用 Enzyme 测试我的惰性组件。以下方法对我有用以测试组件加载完成:

const myComponent = React.lazy(() => 
      import('@material-ui/icons')
      .then(module => ( 
         default: module.KeyboardArrowRight 
      )
   )
);

测试代码->

//mock actual component inside suspense
jest.mock("@material-ui/icons", () =>  
    return 
        KeyboardArrowRight: () => "KeyboardArrowRight",

);

const lazyComponent = mount(<Suspense fallback=<div>Loading...</div>>
           <myComponent>
       </Suspense>);
    
const componentToTestLoaded  = await componentToTest.type._result; // to get actual component in suspense
    
expect(componentToTestLoaded.text())`.toEqual("KeyboardArrowRight");

这很 hacky,但适用于 Enzyme 库。

【讨论】:

以上是关于使用 React Suspense 和 React.lazy 子组件进行 Jest/Enzyme 类组件测试的主要内容,如果未能解决你的问题,请参考以下文章

React Router 和 Suspense 的 404 路由问题

使用 React Suspense 和 React.lazy 子组件进行 Jest/Enzyme 类组件测试

React.lazy和React.Suspense异步加载组件

使用 React.lazy、Suspense 和 react-router-dom 进行代码拆分不起作用

React.lazy和Suspense组合实现组件懒加载

React源码 Suspense 和 ReactLazy