打字稿中 React 测试库包装器的正确输入是什么?
What's the proper typing for a React Testing Library wrapper in typescript?
所以我从 kent c dodd 的图书馆里得到了这样的东西,非常有用
import * as React from 'react'
import {render as rtlRender} from '@testing-library/react'
import {ThemeProvider} from 'components/theme'
function render(ui, {theme = 'light', ...options} = {}) {
const Wrapper = ({children}) => (
<ThemeProvider initialTheme={theme}>{children}</ThemeProvider>
)
return rtlRender(ui, {wrapper: Wrapper, ...options})
}
export * from '@testing-library/react'
// override React Testing Library's render with our own
export {render}
不过我在将它转换为打字稿时遇到了问题。关于下面我需要微调的内容有什么想法吗?
import * as React from 'react'
import { ReactNode } from 'react'
import {render as rtlRender} from '@testing-library/react'
import { QueryClientProvider, QueryClient } from 'react-query'
interface WrapperProps {
children: ReactNode
}
const queryClient = new QueryClient();
function render(ui, {client = queryClient, ...options} = {}) {
const Wrapper = ({children}: WrapperProps) => (
<QueryClientProvider client={client}>
{children}
</QueryClientProvider>
)
return rtlRender(ui, {wrapper: Wrapper, ...options})
}
export * from '@testing-library/react'
// override React Testing Library's render with our own
export {render}
我得到以下关于在包装纸上打字的信息:
No overload matches this call.
Overload 1 of 2, '(ui: ReactElement<any, string | JSXElementConstructor<any>>, options: RenderOptions<typeof import("path/node_modules/@testing-library/dom/types/queries"), HTMLElement>): RenderResult<...>', gave the following error.
Type '({ children }: WrapperProps) => JSX.Element' is not assignable to type 'ComponentType<{}>'.
Type '({ children }: WrapperProps) => JSX.Element' is not assignable to type 'FunctionComponent<{}>'.
Types of parameters '__0' and 'props' are incompatible.
Type '{ children?: ReactNode; }' is not assignable to type 'WrapperProps'.
Property 'children' is optional in type '{ children?: ReactNode; }' but required in type 'WrapperProps'.
Overload 2 of 2, '(ui: ReactElement<any, string | JSXElementConstructor<any>>, options?: Omit<RenderOptions<typeof import("path/node_modules/@testing-library/dom/types/queries"), HTMLElement>, "queries">): RenderResult<...>', gave the following error.
Type '({ children }: WrapperProps) => JSX.Element' is not assignable to type 'ComponentType<{}>'.
Type '({ children }: WrapperProps) => JSX.Element' is not assignable to type 'FunctionComponent<{}>'.ts(2769)
index.d.ts(41, 3): The expected type comes from property 'wrapper' which is declared here on type 'RenderOptions<typeof import("path/node_modules/@testing-library/dom/types/queries"), HTMLElement>'
index.d.ts(41, 3): The expected type comes from property 'wrapper' which is declared here on type 'Omit<RenderOptions<typeof import("path/node_modules/@testing-library/dom/types/queries"), HTMLElement>, "queries">'
您可以这样输入渲染函数
import { render as testingRender, RenderOptions } from "@testing-library/react";
// ...
const render = (
ui: React.ReactElement,
options?: Omit<RenderOptions, "queries">,
) => {
return testingRender(ui, { wrapper: Wrapper, ...options });
};
请注意,我的包装器定义为您的包装器
type WrapperProps = {
children: React.ReactNode;
};
const Wrapper = ({ children }: WrapperProps) => {
return (
<ChakraProvider>
<AuthContext.Provider
value={{
// ...
}}
>
{children}
</AuthContext.Provider>
</ChakraProvider>
);
};
试试这个:
import { ReactElement } from 'react'
import { render as rtlRender } from '@testing-library/react'
import { QueryClientProvider, QueryClient } from 'react-query'
const queryClient = new QueryClient();
const render = (ui: ReactElement, { client = queryClient, ...options } = {}) =>
rtlRender(ui, {
wrapper: ({ children }) => (
<QueryClientProvider client={client}>
{children}
</QueryClientProvider>
), ...options
});
export * from '@testing-library/react'
// override React Testing Library's render with our own
export { render }
理想情况下,您不应该仅仅为了替换渲染函数而导出整个测试库,您可以创建自己的包装器并将其与测试库一起使用。但是,上面的代码应该可以正常工作。
我认为 ts 将 Wrapper
推断为 JSX.Element
,但 rtlRender
需要一个“FunctionComponent”。
因此,您可以 Wrapper: FunctionComponent
或使用其快捷方式 Wrapper: FC
此外,不需要WrapperProps
接口,因为children是spected。
import * as React from 'react'
import { QueryClient, QueryClientProvider } from 'react-query'
import {render as rtlRender} from '@testing-library/react'
const queryClient = new QueryClient();
function render(ui, {client = queryClient, ...options} = {}) {
const Wrapper: React.FC = ({children}) => (
<QueryClientProvider client={client}>
{children}
</QueryClientProvider>
)
return rtlRender(ui, {wrapper: Wrapper, ...options})
}
export * from '@testing-library/react'
// override React Testing Library's render with our own
export {render}
所以我从 kent c dodd 的图书馆里得到了这样的东西,非常有用
import * as React from 'react'
import {render as rtlRender} from '@testing-library/react'
import {ThemeProvider} from 'components/theme'
function render(ui, {theme = 'light', ...options} = {}) {
const Wrapper = ({children}) => (
<ThemeProvider initialTheme={theme}>{children}</ThemeProvider>
)
return rtlRender(ui, {wrapper: Wrapper, ...options})
}
export * from '@testing-library/react'
// override React Testing Library's render with our own
export {render}
不过我在将它转换为打字稿时遇到了问题。关于下面我需要微调的内容有什么想法吗?
import * as React from 'react'
import { ReactNode } from 'react'
import {render as rtlRender} from '@testing-library/react'
import { QueryClientProvider, QueryClient } from 'react-query'
interface WrapperProps {
children: ReactNode
}
const queryClient = new QueryClient();
function render(ui, {client = queryClient, ...options} = {}) {
const Wrapper = ({children}: WrapperProps) => (
<QueryClientProvider client={client}>
{children}
</QueryClientProvider>
)
return rtlRender(ui, {wrapper: Wrapper, ...options})
}
export * from '@testing-library/react'
// override React Testing Library's render with our own
export {render}
我得到以下关于在包装纸上打字的信息:
No overload matches this call.
Overload 1 of 2, '(ui: ReactElement<any, string | JSXElementConstructor<any>>, options: RenderOptions<typeof import("path/node_modules/@testing-library/dom/types/queries"), HTMLElement>): RenderResult<...>', gave the following error.
Type '({ children }: WrapperProps) => JSX.Element' is not assignable to type 'ComponentType<{}>'.
Type '({ children }: WrapperProps) => JSX.Element' is not assignable to type 'FunctionComponent<{}>'.
Types of parameters '__0' and 'props' are incompatible.
Type '{ children?: ReactNode; }' is not assignable to type 'WrapperProps'.
Property 'children' is optional in type '{ children?: ReactNode; }' but required in type 'WrapperProps'.
Overload 2 of 2, '(ui: ReactElement<any, string | JSXElementConstructor<any>>, options?: Omit<RenderOptions<typeof import("path/node_modules/@testing-library/dom/types/queries"), HTMLElement>, "queries">): RenderResult<...>', gave the following error.
Type '({ children }: WrapperProps) => JSX.Element' is not assignable to type 'ComponentType<{}>'.
Type '({ children }: WrapperProps) => JSX.Element' is not assignable to type 'FunctionComponent<{}>'.ts(2769)
index.d.ts(41, 3): The expected type comes from property 'wrapper' which is declared here on type 'RenderOptions<typeof import("path/node_modules/@testing-library/dom/types/queries"), HTMLElement>'
index.d.ts(41, 3): The expected type comes from property 'wrapper' which is declared here on type 'Omit<RenderOptions<typeof import("path/node_modules/@testing-library/dom/types/queries"), HTMLElement>, "queries">'
您可以这样输入渲染函数
import { render as testingRender, RenderOptions } from "@testing-library/react";
// ...
const render = (
ui: React.ReactElement,
options?: Omit<RenderOptions, "queries">,
) => {
return testingRender(ui, { wrapper: Wrapper, ...options });
};
请注意,我的包装器定义为您的包装器
type WrapperProps = {
children: React.ReactNode;
};
const Wrapper = ({ children }: WrapperProps) => {
return (
<ChakraProvider>
<AuthContext.Provider
value={{
// ...
}}
>
{children}
</AuthContext.Provider>
</ChakraProvider>
);
};
试试这个:
import { ReactElement } from 'react'
import { render as rtlRender } from '@testing-library/react'
import { QueryClientProvider, QueryClient } from 'react-query'
const queryClient = new QueryClient();
const render = (ui: ReactElement, { client = queryClient, ...options } = {}) =>
rtlRender(ui, {
wrapper: ({ children }) => (
<QueryClientProvider client={client}>
{children}
</QueryClientProvider>
), ...options
});
export * from '@testing-library/react'
// override React Testing Library's render with our own
export { render }
理想情况下,您不应该仅仅为了替换渲染函数而导出整个测试库,您可以创建自己的包装器并将其与测试库一起使用。但是,上面的代码应该可以正常工作。
我认为 ts 将 Wrapper
推断为 JSX.Element
,但 rtlRender
需要一个“FunctionComponent”。
因此,您可以 Wrapper: FunctionComponent
或使用其快捷方式 Wrapper: FC
此外,不需要WrapperProps
接口,因为children是spected。
import * as React from 'react'
import { QueryClient, QueryClientProvider } from 'react-query'
import {render as rtlRender} from '@testing-library/react'
const queryClient = new QueryClient();
function render(ui, {client = queryClient, ...options} = {}) {
const Wrapper: React.FC = ({children}) => (
<QueryClientProvider client={client}>
{children}
</QueryClientProvider>
)
return rtlRender(ui, {wrapper: Wrapper, ...options})
}
export * from '@testing-library/react'
// override React Testing Library's render with our own
export {render}