想知道是否有人对如何破解这个问题有一些好的建议.得到了这个测试助手utils,我添加了一些类型:

imp或t { jest } from '@jest/globals'
imp或t React from 'react'

// https://learn.reactnativeschool.com/courses/781007/lectures/14173979
exp或t function mockComponent(moduleName: string, propOverrideFn = (props: Rec或d<string, any>) => ({})) {
  const RealComponent = jest.requireActual(moduleName) as React.ComponentType<any>
  const CustomizedComponent = (props: Rec或d<string, any>) => {
    return React.createElement(
      'CustomizedComponent',
      {
        ...props,
        ...propOverrideFn(props),
      },
      props.children
    )
  }
  CustomizedComponent.propTypes = RealComponent.propTypes

  return CustomizedComponent
}

所以现在我可以这样称呼它

jest.mock('react-native/Libraries/Components/Touchable/TouchableOpacity', () => {
  return mockComponent('react-native/Libraries/Components/Touchable/TouchableOpacity', (props) => {
    return {
      onPress: props.disabled ? () => {} : props.onPress
    }
  })
})

但我希望能称之为


jest.mock('react-native/Libraries/Components/Touchable/TouchableOpacity', () => {
  return <MockComponent 
          module='TouchableOpacity' 
          onPress={props => props.disabled ? () => {} : props.onPress}
         />
})

jest.mock('react-native/Libraries/Components/Touchable/TouchableOpacity', () => {
 return <MockComponent 
          module='TouchableOpacity'
          propOverride={props => ({onPress: props.disabled ? () => {} : props.onPress, ...props})}
        />
})

推荐答案

如果你看React without JSX,你会发现受XML启发的语法(<MockComponent />)只是React.createElement('MockComponent')的缩写.

现在,如果将mockComponent重命名为MockComponent,并try 使用尖括号语法,那么first的问题是函数接收两个参数.React组件可以是采用一个构造函数参数(props)的类组件,也可以是采用一个参数(同样,props)的函数组件.问题在于,当函数需要返回rendered React元素时,它会返回一个React函数组件.

解决这个问题的一种方法是将mockComponent转化为React功能组件,并制作modulepropOverride个FCprops .

// https://learn.reactnativeschool.com/courses/781007/lectures/14173979
export function MockComponent(props) {
  const { moduleName, propOverrideFn, ...customComponentProps } = props;

  const RealComponent = jest.requireActual(moduleName) as React.ComponentType<any>
  const CustomizedComponent = (props: Record<string, any>) => {
    return React.createElement(
      'CustomizedComponent',
      {
        ...props,
        ...propOverrideFn(props),
      },
      props.children
    )
  }
  CustomizedComponent.propTypes = RealComponent.propTypes

  return <CustomizedComponent {...customComponentProps} />
}

这些差异很微妙,但很重要.在这里,我修改了MockComponent,以接受一个与React.createElement()兼容的单数prop参数.这就引出了一个问题:如何区分CustomizedComponent的props 和mockComponent()的参数.在这里,我使用JavaScript解构和扩展操作符将modulepropOverrideCustomizedComponent的props 分开.

最后,我使用JSX spread syntax将用于CustomizedComponent的任意props 传递到CustomizedComponent,并使用尖括号进行渲染(而不是返回函数).

作为练习,我将为MockComponent的props 提供适当的TypeScript定义.您可以简单地将其定义为记录的并集<;任何字符串>;modulepropOverride.然而,你可以使用一个模板定义,所以MockComponent<Toolbar>modulepropOverride以及Toolbar的props 的结合.

哦,我差点忘了.你的jest电话看起来像

jest.mock('react-native/Libraries/Components/Touchable/TouchableOpacity', () => {
    (props) => {
        return <MockComponent 
            module='TouchableOpacity' 
            onPress={props => props.disabled ? () => {} : props.onPress}
            {...props}
        />
   }
})

Javascript相关问答推荐

如何在JavaScript中通过一次单击即可举办多个活动

为什么在获取回调内设置状态(不会)会导致无限循环?

确定MutationRecord中removedNodes的索引

Redux工具包查询(RTKQ)端点无效并重新验证多次触发

使用续集和下拉栏显示模型属性

Google图表时间轴—更改hAxis文本 colored颜色

React Code不在装载上渲染数据,但在渲染上工作

在react js中使用react—router—dom中的Link组件,分配的右侧不能被 destruct ''

在带有背景图像和圆形的div中添加长方体阴影时的重影线

如何在 cypress 中使用静态嵌套循环

在Three JS中看不到补间不透明度更改效果

当使用';字母而不是与';var#39;一起使用时,访问窗口为什么返回未定义的?

环境值在.js文件/Next.js中不起作用

一个实体一刀VS每个实体多刀S

在JS中动态创建对象,并将其追加到HTML表中

使用jQuery find()获取元素的属性

无法设置RazorPay订阅API项目价格

P5.js中的分形树

重新渲染过多(&Q).REACT限制渲染次数以防止无限循环.使用REACT下拉菜单时

无法向甜甜圈图表上的ChartJSImage添加可见标签