如何使用 React 测试库测试 Create-React-App(在 TypeScript 中)的特定元素

How to test specific elements of a Create-React-App (in TypeScript) with react testing library

我使用带有 --typescript 选项的 create-react-app 生成了一个项目。

这是我的应用程序:

import React from 'react';

const App: React.FC = () => {
  return (
    <div className="App">
        <div>
            <h1 id="pageHeader">Home page</h1>
            <p>This is the Home page</p>
        </div>
    </div>
  );
};

export default App;

我目前的测试是:

import React from 'react';
import ReactDOM from 'react-dom';
import {render} from '@testing-library/react';
import "@testing-library/jest-dom/extend-expect";
import App from './App';

test('Verify page header', () => {
    const {getByText} = render(<App/>);
    expect(getByText('Home page')).toBeInTheDocument;
});

问题: 我想再测试一下。除了测试“主页”是否出现在我页面的任何位置之外,我还想确保文本“主页”位于 h1 元素中。如何从 react-testing-library 获取完整元素(最好通过 getElementById)以便我可以使用 Jest 对其进行断言?

我是这样解决的:

test('Verify page header', () => {
    const {container} = render(<App/>);
    const pageHeaderElement = container.querySelector('#pageHeader');
    if (pageHeaderElement) {
        const pageHeaderElementContent = pageHeaderElement.firstChild;
        if (pageHeaderElementContent) {
            // You can either do:
            expect(pageHeaderElementContent.textContent).toMatch('Home page');
            // Or:
            expect(pageHeaderElementContent).toMatchInlineSnapshot('Home page');
        } else {
            fail('Should have existed.');
        }
    } else {
        fail('Should have existed.');
    }
});

我在 react-testing 库的文档中发现了这个 toMatchInlineSnapshot 方法: https://testing-library.com/docs/react-testing-library/api#render

带有新的 TypeScript 可选链接的较短版本:

test('Verify page header', () => {
    const {container} = render(<App/>);
    const pageHeaderContent = container.querySelector("#pageHeader")?.firstChild?.textContent;
    expect(pageHeaderContent).toMatch('Home page');
});

几点,根据你自己的回答:

  1. 您应该避免在测试中出现任何逻辑分支。测试中的逻辑可能会导致不稳定的测试,因为测试中的逻辑没有经过测试。在您的情况下,if 块是不必要的,因为如果文本内容不存在,测试将已经失败。

  2. 有几种简单的方法可以测试文本 "Home Page" 是否在 h1 中:

查找文本并期望元素为 h1:

test('Verify page header', () => {
    const {getByText} = render(<App/>);
    expect(getByText('Home page').tagName).toBe('H1');
});

或者给 h1 一个 data-testid 并使用 getByTestId:

<h1 data-testid="pageHeader">Home Page</h1> // <-- In your component

test('Verify page header', () => {
    const {getByTestId} = render(<App/>);
    expect(getByTestId('pageHeader').textContent).toBe('Home Page');
});