Reactjs 如何测试异步void函数中的潜在空值,而不在TypeScript中使用@ts ignore
这可能更像是一个JavaScript/TypeScript问题,而不是关于反应/测试 但我会给出完整的故事。所以我有一个带有基本路由功能的测试应用程序,并通过测试来验证路由是否有效 App.tsx App.test.tsx 一切都很顺利。然后我添加了一个useEffect钩子来初始化我的国际化库:Reactjs 如何测试异步void函数中的潜在空值,而不在TypeScript中使用@ts ignore,reactjs,typescript,jestjs,react-testing-library,Reactjs,Typescript,Jestjs,React Testing Library,这可能更像是一个JavaScript/TypeScript问题,而不是关于反应/测试 但我会给出完整的故事。所以我有一个带有基本路由功能的测试应用程序,并通过测试来验证路由是否有效 App.tsx App.test.tsx 一切都很顺利。然后我添加了一个useEffect钩子来初始化我的国际化库: useEffect(() => { async function initMessages() { await intl.init({ cur
useEffect(() => {
async function initMessages() {
await intl.init({
currentLocale: "en-US",
locales
});
}
initMessages().then(() => setLoading(false));
}, [loading]);
这将加载我所有的英文文本资源。这工作正常,但由于以下错误消息而中断了所有测试:
警告:测试中的应用程序更新未包装在act(…)中。
经过一些阅读,我通过添加此“act”函数修复了测试,下面是一个示例:
import React from 'react';
import {act, render, fireEvent, waitForElement} from '@testing-library/react';
import "@testing-library/jest-dom/extend-expect";
import App from './App';
test('Verify home page header', async() => {
let app: HTMLElement;
await act(async () => {
const {container} = render(<App/>);
app = container;
});
// @ts-ignore
if (app) {
const pageHeaderContent = app.querySelector("#pageHeader")?.firstChild?.textContent;
expect(pageHeaderContent).toMatch('Home page');
} else {
fail("The app should have been initialized.");
}
});
从“React”导入React;
从'@testing library/react'导入{act,render,firevent,waitForElement};
导入“@测试库/jest dom/extend expect”;
从“./App”导入应用程序;
测试('Verify home page header',async()=>{
let-app:HTMLElement;
等待动作(异步()=>{
常量{container}=render(
指向上次提交的链接:Typescript抱怨当您在if语句中访问应用程序变量时,该变量尚未初始化。您只需将null
赋值给它即可解决此问题
let app: HTMLElement = null;
如果使用严格的null检查,则必须允许类型为null:
let app: HTMLElement | null = null;
经过深思熟虑,这就是我的结果
test('Verify home page header', async() => {
let app: HTMLElement | undefined = undefined;
await act(async () => {
const {container} = render(<App/>);
app = container;
});
let appAsHtmlElement = (app as unknown as HTMLElement);
const pageHeaderContent = appAsHtmlElement.querySelector("#pageHeader")?.firstChild?.textContent;
expect(pageHeaderContent).toMatch('Home page');
});
test('Verify home page header',async()=>{
let app:HTMLElement |未定义=未定义;
等待动作(异步()=>{
const{container}=render();
app=容器;
});
让appAsHtmlElement=(应用程序与HTMLElement一样未知);
const pageHeaderContent=appashtmlement.querySelector(“#pageHeader”)?.firstChild?.textContent;
expect(pageHeaderContent.toMatch('homepage');
});
更好的建议(如果有某种方式不必使用“act”功能)仍然受欢迎。它可以是未定义的,但您声明它仅为HTMLElement?TypeScript无法判断act
是否将调用回调,并且无法保证将定义app
。您可以尝试在另一个承诺中包装act
,该承诺将在回调内部通过app
解决。您可能还需要等待act
解决后才能继续。正如@alexey所说的。您可以将测试代码移到回调中。这会让TS闭嘴,因为这将保证应用程序被定义。@colefner他尝试过这样做,但这违背了act
的目的,即允许React完成所有li在使用expect
进行断言之前,fecycle钩子。啊,是的,我错过了那一部分。这很好,@AlexeyLebedev