React 测试库:测试元素是否已被映射/渲染 [英] React Testing Library: Test if Elements have been mapped/rendered

查看:46
本文介绍了React 测试库:测试元素是否已被映射/渲染的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题:

我有一个项目列表,我想通过每个项目 name 值(字符串)来测试.我正在使用 @testing-library/react 并让测试套件正常工作,但我无法让我的测试工作.

概述:

  • 每个item 都有一个data-testid="side-menu-link" 的测试ID.这必须是唯一的还是可以按原样进行测试?
  • 菜单项由DashboardSettingsUser Preferences 等字符串组成

DisplayItems.test.tsx:

//导入:依赖从反应"导入反应;从'@testing-library/react'导入{渲染,屏幕};//导入:应用从'../../App'导入应用程序;//侧面菜单:仪表板test('正确渲染仪表板', () => {//渲染:应用const { getByTestId } = render();//预计expect(getByTestId('side-menu-link')).toHaveAttribute('Dashboard')});//侧边菜单:用户首选项test('正确渲染仪表板', () => {//渲染:应用const { getByTestId } = render();//预计expect(getByTestId('side-menu-link')).toHaveAttribute('User Preferences')});

地图项目:

//映射菜单项return menuItems.map((menuItem, i) => {返回 (<Link data-testid="side-menu-link";key={i} href=#";className="side-menu-link";to={`/${menuItem.itemName}`}><div className={props.currenttab === `${menuItem.itemName}` ?'side-menu-item-container-selected-light':'side-menu-item-container-light'}>{menuItem.itemIcon}<p className={props.currenttab === `${menuItem.itemName}` ?'side-menu-title-selected-light':'side-menu-title-light'}>{menuItem.itemName}</p>

</链接>);});

解决方案

您可以有多个 testID.否则,就不会有 __AllByTestId 选择器.这个名字似乎没有经过深思熟虑,因为它与 HTML id 相似,必须是唯一的.

如果您使用 __ByTestId 但您有多个具有匹配测试 ID 的元素,则会发生抛出:

it(queryByTestId 将抛出多个 testID", () => {const {queryAllByTestId, queryByTestId} = render(<查看><Text testID="foo">a</Text><Text testID="foo">b</Text></查看>);期望(queryAllByTestId(foo")).toHaveLength(2);//好的queryByTestId("foo");//=>错误:找到多个 testID 为 foo 的元素});

要测试地图,您可以向子项添加测试 ID 并使用上述模式.

反应原生:

import "@testing-library/jest-native/extend-expect";//...it(应该在所有孩子中找到文本内容", () => {const {queryAllByTestId} = 渲染(<查看>{[...abcd"].map((e, i) =><查看键={e + i} testID=foo"><Text>{e}</Text></View>)}</查看>);期望(queryAllByTestId(foo")).toHaveLength(4);[...abcd"].forEach((e, i) => {期望(queryAllByTestId(foo")[i]).toHaveTextContent(e);});});

反应:

it(应该在所有孩子中找到文本内容", () => {const {queryAllByTestId} = 渲染(<ul>{[...abcd"].map((e, i) =><li key={e + i} data-testid=foo">{e}</li>)});期望(queryAllByTestId(foo")).toHaveLength(4);[...abcd"].forEach((e, i) => {期望(queryAllByTestId(foo")[i].textContent).toEqual(e);});//或者://const contents = queryAllByTestId("foo").map(e => e.textContent);//expect(contents).toEqual([...abcd"]);});

还可以将 testID 添加到映射列表元素的父级,选择父级,然后遍历其 .children 数组以对每个子级进行断言树.

注意 RN 中的 testID 和 React 中的 data-testid 之间的区别.


顺便说一句,我不确定

expect(getByTestId('side-menu-link')).toHaveAttribute('User Preferences')

在这里很有意义.属性是 <div this_is_an_attribute="foo"> -- 您可能正在寻找文本内容.


使用的包,供参考:

反应原生

{依赖关系":{反应":^ 17.0.2",react-dom":^17.0.2",反应原生":^ 0.64.0",react-native-web":^0.15.6";},开发依赖":{@babel/core":^7.13.15",@testing-library/jest-native":^4.0.1",@testing-library/react-native":^7.2.0",babel-jest":^26.6.3",开玩笑":^26.6.3",metro-react-native-babel-preset":^0.65.2",反应测试渲染器":^ 17.0.2";}}

反应

{依赖关系":{@babel/runtime":7.10.5",反应":16.13.1",反应DOM":16.13.1",},开发依赖":{@babel/core":7.10.5",@babel/plugin-proposal-class-properties":7.10.4",@babel/preset-env":7.10.4",@babel/preset-react":7.10.4",@testing-library/dom":7.21.0",@testing-library/jest-dom":^5.11.1",@testing-library/react":10.4.7",@testing-library/react-hooks":3.3.0",@testing-library/user-event":12.0.11",babel-jest":26.1.0",开玩笑":26.1.0",jest-environment-jsdom":26.1.0",反应测试渲染器":16.13.1",}}

Issue:

I have a list of Items that I want to test by each one of the items name value (string). I'm using @testing-library/react and have the test suite correctly working, but I can't get my test to work.

Overview:

  • Each item has a test id of data-testid="side-menu-link". Does this have to be unique or can it be tested as is?
  • The menuItems consist of strings like Dashboard, Settings, and User Preferences

DisplayItems.test.tsx:

// Imports: Dependencies
import React from 'react';
import { render, screen } from '@testing-library/react';

// Imports: App
import App from '../../App';

// Side Menu: Dashboard
test('Renders Dashboard correctly', () => {
  // Render: App
  const { getByTestId } = render(<App />);

  // Expect
  expect(getByTestId('side-menu-link')).toHaveAttribute('Dashboard')
});


// Side Menu: User Preferences
test('Renders Dashboard correctly', () => {
  // Render: App
  const { getByTestId } = render(<App />);

  // Expect
  expect(getByTestId('side-menu-link')).toHaveAttribute('User Preferences')
});

Map Items:

// Map Menu Items
return menuItems.map((menuItem, i) => {
  return (
    <Link data-testid="side-menu-link" key={i} href="#" className="side-menu-link" to={`/${menuItem.itemName}`}>
      <div className={props.currenttab === `${menuItem.itemName}` ? 'side-menu-item-container-selected-light' : 'side-menu-item-container-light'}>
        {menuItem.itemIcon}
        <p className={props.currenttab === `${menuItem.itemName}` ? 'side-menu-title-selected-light' : 'side-menu-title-light'}>{menuItem.itemName}</p>
      </div>
    </Link>
  );
});

解决方案

You can have multiple testIDs. Otherwise, there wouldn't be __AllByTestId selectors. The name wasn't well-thought out, it seems, because of similarity to HTML ids which must be unique.

A throw happens if you use __ByTestId yet you have multiple elements with the matching test id:

it("queryByTestId will throw with multiple testIDs", () => {
  const {queryAllByTestId, queryByTestId} = render(
    <View>
      <Text testID="foo">a</Text>
      <Text testID="foo">b</Text>
    </View>
  );
  expect(queryAllByTestId("foo")).toHaveLength(2); // OK
  queryByTestId("foo"); // => Error: Found multiple elements with testID: foo
});

To test a map, you can add test ids to the children and use the above pattern.

React Native:

import "@testing-library/jest-native/extend-expect";

// ...

it("should find text content in all children", () => {
  const {queryAllByTestId} = render(
    <View>
      {[..."abcd"].map((e, i) => 
        <View key={e + i} testID="foo"><Text>{e}</Text></View>
      )}
    </View>
  );

  expect(queryAllByTestId("foo")).toHaveLength(4);
  
  [..."abcd"].forEach((e, i) => {
    expect(queryAllByTestId("foo")[i]).toHaveTextContent(e);
  });
});

React:

it("should find text content in all children", () => {
  const {queryAllByTestId} = render(
    <ul>
      {[..."abcd"].map((e, i) => 
        <li key={e + i} data-testid="foo">{e}</li>
      )}
    </ul>
  );

  expect(queryAllByTestId("foo")).toHaveLength(4);

  [..."abcd"].forEach((e, i) => {
    expect(queryAllByTestId("foo")[i].textContent).toEqual(e);
  });

  // or:
  //const contents = queryAllByTestId("foo").map(e => e.textContent);
  //expect(contents).toEqual([..."abcd"]);
});

It's also possible to add a testID to the parent of the mapped list elements, select the parent, then traverse over its .children array to make assertions on each child tree.

Note the differences between testID in RN and data-testid in React.


As a side note, I'm not sure

expect(getByTestId('side-menu-link')).toHaveAttribute('User Preferences')

makes much sense here. attributes are <div this_is_an_attribute="foo"> -- you're probably looking for text content.


Packages used, for reference:

React Native

{
  "dependencies": {
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-native": "^0.64.0",
    "react-native-web": "^0.15.6"
  },
  "devDependencies": {
    "@babel/core": "^7.13.15",
    "@testing-library/jest-native": "^4.0.1",
    "@testing-library/react-native": "^7.2.0",
    "babel-jest": "^26.6.3",
    "jest": "^26.6.3",
    "metro-react-native-babel-preset": "^0.65.2",
    "react-test-renderer": "^17.0.2"
  }
}

React

{
  "dependencies": {
    "@babel/runtime": "7.10.5",
    "react": "16.13.1",
    "react-dom": "16.13.1",
  },
  "devDependencies": {
    "@babel/core": "7.10.5",
    "@babel/plugin-proposal-class-properties": "7.10.4",
    "@babel/preset-env": "7.10.4",
    "@babel/preset-react": "7.10.4",
    "@testing-library/dom": "7.21.0",
    "@testing-library/jest-dom": "^5.11.1",
    "@testing-library/react": "10.4.7",
    "@testing-library/react-hooks": "3.3.0",
    "@testing-library/user-event": "12.0.11",
    "babel-jest": "26.1.0",
    "jest": "26.1.0",
    "jest-environment-jsdom": "26.1.0",
    "react-test-renderer": "16.13.1",
  }
}

这篇关于React 测试库:测试元素是否已被映射/渲染的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆