如何在不使用 TypeScript 中的 @ts-ignore 的情况下从异步无效函数测试潜在的空值
How to test a potential null value from an async void function without using @ts-ignore in TypeScript
这可能更像是一个 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-ignore 抑制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子句进行null检查的情况下,获取render函数解构的容器对象?
我为与此问题相关的当前代码创建了一个标签:
https://github.com/Leejjon/pwa-seo/releases/tag/uglylines
Link 最后一次提交:https://github.com/Leejjon/pwa-seo/commit/2434f78c0619be2d55f9de965149f6bd6d1a0b90
当您在 if 语句中访问它时,Typescript 抱怨 app 变量没有被初始化。您可以通过将 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' 功能的方法)。
这可能更像是一个 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(...).
经过一番阅读
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-ignore 抑制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子句进行null检查的情况下,获取render函数解构的容器对象?
我为与此问题相关的当前代码创建了一个标签: https://github.com/Leejjon/pwa-seo/releases/tag/uglylines Link 最后一次提交:https://github.com/Leejjon/pwa-seo/commit/2434f78c0619be2d55f9de965149f6bd6d1a0b90
当您在 if 语句中访问它时,Typescript 抱怨 app 变量没有被初始化。您可以通过将 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' 功能的方法)。