Nor*_*ldt 6 javascript typescript reactjs jestjs react-native
想知道是否有人对如何解决这个问题有一些好的建议。得到了这个测试助手实用程序,我添加了一些类型:
import { jest } from '@jest/globals'
import React from 'react'
// https://learn.reactnativeschool.com/courses/781007/lectures/14173979
export function mockComponent(moduleName: string, propOverrideFn = (props: Record<string, any>) => ({})) {
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
}
Run Code Online (Sandbox Code Playgroud)
所以目前我可以这样称呼它
jest.mock('react-native/Libraries/Components/Touchable/TouchableOpacity', () => {
return mockComponent('react-native/Libraries/Components/Touchable/TouchableOpacity', (props) => {
return {
onPress: props.disabled ? () => {} : props.onPress
}
})
})
Run Code Online (Sandbox Code Playgroud)
但我希望能够更像这样称呼它
jest.mock('react-native/Libraries/Components/Touchable/TouchableOpacity', () => {
return <MockComponent
module='TouchableOpacity'
onPress={props => props.disabled ? () => {} : props.onPress}
/>
})
Run Code Online (Sandbox Code Playgroud)
或者
jest.mock('react-native/Libraries/Components/Touchable/TouchableOpacity', () => {
return <MockComponent
module='TouchableOpacity'
propOverride={props => ({onPress: props.disabled ? () => {} : props.onPress, ...props})}
/>
})
Run Code Online (Sandbox Code Playgroud)
如果您查看没有 JSX 的 React,您会发现受 XML 启发的语法 ( <MockComponent />) 只是 的缩写React.createElement('MockComponent')。
现在,如果您重命名mockComponent为MockComponent并尝试使用尖括号语法,第一个问题是您的函数接收两个参数。React 组件要么是采用一个构造函数参数(props)的类组件,要么是采用一个参数(同样是 props)的函数组件。第二个问题是,当您的函数需要返回渲染的React元素时,它会返回 React 功能组件。
解决这个问题的一种方法是转换mockComponent为 React 功能组件以及FC 的makemodule和props。propOverride
// 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} />
}
Run Code Online (Sandbox Code Playgroud)
差异很微妙但很重要。这里我修改MockComponent为采用单一prop参数以与React.createElement(). 这导致了如何区分用于 的 propsCustomizedComponent和用于 的参数的问题mockComponent()。在这里,我使用 JavaScript 解构和扩展运算符将module和propOverride与 的 props分开CustomizedComponent。
最后,我使用JSX 扩展语法将用于的任意属性传递到CustomizedComponentinto CustomizedComponent,并使用尖括号来渲染它(而不是返回函数)。
我将留下一个练习,让您为 MockComponent 的 props 提供适当的 TypeScript 定义。module您可以简单地将其定义为 Record<string, any> 和and的并集propOverride。但是,您可以使用模板定义,and和的 props 的MockComponent<Toolbar>并集也是如此。modulepropOverrideToolbar
哦,我差点忘了。你的 Jest 电话看起来像
jest.mock('react-native/Libraries/Components/Touchable/TouchableOpacity', () => {
(props) => {
return <MockComponent
module='TouchableOpacity'
onPress={props => props.disabled ? () => {} : props.onPress}
{...props}
/>
}
})
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
387 次 |
| 最近记录: |