如何在不使用 TypeScript 中@ts-ignore 的情况下测试异步 void 函数的潜在空值



这可能更像是一个JavaScript/TypeScript问题,而不是关于React/Testing的问题。

但我会给出完整的故事。所以我有一个具有基本路由功能的测试应用程序,并测试以验证路由是否有效。

App.tsx https://github.com/Leejjon/pwa-seo/blob/6f621968de1184b03744a262a68d291b4571c5c1/src/App.tsx

App.test.tsx https://github.com/Leejjon/pwa-seo/blob/6f621968de1184b03744a262a68d291b4571c5c1/src/App.test.tsx

一切都很好。然后我添加了一个 useEffect 钩子来初始化我的国际化库:

useEffect(() => {
async function initMessages() {
await intl.init({
currentLocale: "en-US",
locales
});
}
initMessages().then(() => setLoading(false));
}, [loading]);

这将以英语加载我的所有文本资产。这工作正常,但因以下错误消息而破坏了我的所有测试:Warning: An update to App inside a test was not wrapped in 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.");
}
});

现在我正在用@ts忽略来抑制TS2454: Variable 'app' is used before being assigned.警告。这很丑陋。如果我将断言移动到 act 函数中,我会再次收到相同的Warning: An update to App inside a test was not wrapped in act(...).错误。

有没有办法获取从渲染函数解构的容器对象,而不必使用 @ts-ignore 和 if 子句来执行空检查?

我为与此问题相关的当前代码创建了一个标签: https://github.com/Leejjon/pwa-seo/releases/tag/uglylines 链接到上次提交:https://github.com/Leejjon/pwa-seo/commit/2434f78c0619be2d55f9de965149f6bd6d1a0b90

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');
});

更好的建议(如果有某种方法不必使用"act"功能(仍然受到欢迎。

最新更新