React TDD - 如何获取内部文本?
React TDD - How do I get inner text?
我正在 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 HTMLElement
的直接文档或 VSCode 中的智能感知都不是正在向我展示任何明显可以使用的东西。也许我测试集合中的项目的方法可以完全不同?
来自 byrole/#api 文档,
Please note that setting a role
and/or aria-*
attribute that matches the implicit ARIA semantics is unnecessary and is not recommended as these properties are already set by the browser, and we must not use the role
and aria-*
attributes in a manner that conflicts with the semantics described. For example, a button
element can't have the role
attribute of heading
, because the button
element has default characteristics that conflict with the heading
role.
您无法为 li
设置 provider
角色,li
的默认和所需角色是由浏览器设置的 listitem
。
此外,jestjs使用jsdom
作为其测试环境,HTMLELement.innerText
属性在jsdom
中没有实现,请参见issue#1245. You can use 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
我正在 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 HTMLElement
的直接文档或 VSCode 中的智能感知都不是正在向我展示任何明显可以使用的东西。也许我测试集合中的项目的方法可以完全不同?
来自 byrole/#api 文档,
Please note that setting a
role
and/oraria-*
attribute that matches the implicit ARIA semantics is unnecessary and is not recommended as these properties are already set by the browser, and we must not use therole
andaria-*
attributes in a manner that conflicts with the semantics described. For example, abutton
element can't have therole
attribute ofheading
, because thebutton
element has default characteristics that conflict with theheading
role.
您无法为 li
设置 provider
角色,li
的默认和所需角色是由浏览器设置的 listitem
。
此外,jestjs使用jsdom
作为其测试环境,HTMLELement.innerText
属性在jsdom
中没有实现,请参见issue#1245. You can use 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