如何断言哪个值已传递给 <li> 键属性以与 jest 和 testing-library/react 反应

Posted

技术标签:

【中文标题】如何断言哪个值已传递给 <li> 键属性以与 jest 和 testing-library/react 反应【英文标题】:How can I assert which value has been passed to a <li> key attribute in react with jest and testing-library/react 【发布时间】:2021-12-13 22:07:48 【问题描述】:

我正在使用 react+ts 和 jest+testing-library 进行测试。我想对以下代码进行单元测试,并希望确保将 person.id 设置为 li 元素的 key 属性. 最初我以为我可以通过运行expect(listItems[1]).toHaveAttribute('key', '2'); 来断言它,但似乎 key 属性已从最终的 html 中删除,这似乎是我正在测试的。如何确保将 person.id 传递给列表项的 key 属性?

import React from 'react';
import Api from '../control/api';

const PersonList = () => 
    const persons = Api.getPersons();

    return (
        <ul>
            persons.map((person) => 
                return (
                    <li key=person.id>
                        `$person.id: $person.name.familyName, $person.name.givenName`
                    </li>
                );
            )
        </ul>
    );
;

export default PersonList;

测试:

import React from 'react';
import  render, screen  from '@testing-library/react';
import PersonList from '../../components/PersonList';
import  getPersons  from '../../control/api';

jest.mock('../../control/api');

const mockGetPersons = getPersons as jest.MockedFunction<typeof getPersons>;

describe('The PersonList component', () => 
    it('should output empty list if there are no persons returned by the api', () => 
        mockGetPersons.mockReturnValue([]);

        render(<PersonList />);

        const lists = screen.getAllByRole('list');
        expect(lists).toHaveLength(1);
    );

    it('should render one person returned by api', () => 
        mockGetPersons.mockReturnValue([
            
                id: '1',
                name: 
                    familyName: 'Duck',
                    givenName: 'Donald',
                ,
            ,
        ]);

        render(<PersonList />);

        const listItems = screen.getAllByRole('listitem');
        expect(listItems).toHaveLength(1);
        expect(listItems[0]).toHaveTextContent('1: Duck, Donald');
    );

    it('should render several persons returned by api', () => 
        mockGetPersons.mockReturnValue([
            
                id: '1',
                name: 
                    familyName: 'Duck',
                    givenName: 'Donald',
                ,
            ,
            
                id: '2',
                name: 
                    familyName: 'Duck',
                    givenName: 'Dagobert',
                ,
            ,
            
                id: '3',
                name: 
                    familyName: 'Mouse',
                    givenName: 'Mickey',
                ,
            ,
        ]);

        render(<PersonList />);

        const listItems = screen.getAllByRole('listitem');
        expect(listItems).toHaveLength(3);
        expect(listItems[0]).toHaveTextContent('1: Duck, Donald');
        // expect(listItems[1]).toHaveAttribute('key', '2');
        expect(listItems[2]).toHaveTextContent('3: Mouse, Mickey');
    );
);

【问题讨论】:

在单元测试中测试实现细节通常是一种反模式。为什么要对此进行测试? 关键属性是特定于反应的。试试key 以外的其他东西,比如data-key 您好,感谢您的回答!我对此进行了更多思考,并意识到了我的错误。我的印象是我必须从另一个组件“手动”访问 li 的关键属性。这就是为什么我想断言它们得到了正确的值。但是 react 仅在内部使用 key 属性,只要 key 对列表中的每个项目都是唯一的,我作为 key 传递的内容并不重要。 【参考方案1】:

key 属性是 react 内部使用的,它设置什么并不重要,只要当前列表中每个项目的值都是唯一的。因此,代码的任何用户(无论是最终用户还是开发人员)都不会使用/查看/知道那里设置的值,这意味着我们不应该编写测试来断言 key 属性。

更多关于key property in the react docs

关于Testing Implementation Details的博客文章

关于 Accessing the key property 编程的 *** 问题

【讨论】:

以上是关于如何断言哪个值已传递给 <li> 键属性以与 jest 和 testing-library/react 反应的主要内容,如果未能解决你的问题,请参考以下文章

使用构造函数将数组传递给对象后,值已更改(在 c++ 中)。我想不通为啥

如何断言显示为字符串的货币值已正确更新

DeprecationWarning:布尔值已传递给 options.operatorsAliases。这是 v5 的无操作,应删除

如何将Django中列表的值传递给方法?

如何在spring mvc中将嵌套列表元素传递给控制器

将未初始化的内存传递给函数时如何断言/测试