首页 > 解决方案 > React TDD - 如何获取内部文本?

问题描述

我正在 React 中进行 TDD(使用 Typescript,以防万一)来构建一个非常简单的 oauth 登录页面。因为我希望能够支持多个提供程序,所以我对元素进行参数化的第一个测试如下所示:

  it("should have providers", () => {
    const { getAllByRole } = render(<Login></Login>);
    const providers: string[] = getAllByRole("provider").map((element) => {
      return element.innerText;
    });
    expect(providers).toContain("GitHub");
  });

我的组件目前非常简单,现在只对元素进行了硬编码:

const Login = () => {
  return (
    <div role="login">
      <header>Login with SSO</header>
      <ul>
        <li role="provider">GitHub</li>
      </ul>
    </div>
  );
};

export default Login;

我以为我的测试会将所有元素转换为它们的文本内容(例如:)string[],但是我得到了一个数组undefined

  ● Login Component › should have providers

    expect(received).toContain(expected) // indexOf

    Expected value: "GitHub"
    Received array: [undefined]

我认为问题在于它innerText没有初始化,我应该调用另一个字段或方法,但是interface HTMLElementVSCode 中的即时文档或智能感知都没有向我展示任何明显可以使用的东西。也许我测试一个项目的方法是在一个集合中可以完全不同地完成?

标签: reactjstypescriptreact-testing-library

解决方案


来自byrole/#api文档,

请注意,设置与隐式 ARIA 语义相匹配的roleand/oraria-*属性是不必要的,也不建议这样做,因为这些属性已经由浏览器设置,并且我们不能以与所描述的语义相冲突的方式使用roleandaria-*属性。例如,一个button元素不能具有 的role属性heading,因为该button元素具有与heading角色冲突的默认特性。

无法设置provider角色li,默认角色和所需角色由浏览器设置lilistitem

此外,jestjsjsdom用作其测试环境,HTMLELement.innerTextproperty 没有实现jsdom,见issue#1245。您可以改用Node.textContent

Login.tsx

import React from 'react';

const Login = () => {
  return (
    <div role="login">
      <header>Login with SSO</header>
      <ul>
        <li>GitHub</li>
        <li>Google</li>
      </ul>
    </div>
  );
};

export default Login;

Login.test.tsx

import { render, screen } from '@testing-library/react';
import React from 'react';
import Login from './Login';

describe('Login', () => {
  it('should have providers', () => {
    const { getAllByRole } = render(<Login />);
    const providers: Array<string | null> = getAllByRole('listitem').map((element) => {
      return element.textContent;
    });
    console.log(providers);
    expect(providers).toContain('GitHub');
  });
});

测试结果:

 PASS  examples/69970652/Login.test.tsx (10.053 s)
  Login
    ✓ should have providers (124 ms)

  console.log
    [ 'GitHub', 'Google' ]

      at Object.<anonymous> (examples/69970652/Login.test.tsx:11:13)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        10.6 s, estimated 11 s

推荐阅读