如何使用 react-testing-library 测试锚的 href
Posted
技术标签:
【中文标题】如何使用 react-testing-library 测试锚的 href【英文标题】:How to test anchor's href with react-testing-library 【发布时间】:2020-01-09 15:12:30 【问题描述】:我正在尝试测试我的锚标记。一旦我点击它,我想看看window.location.href
是否是我所期望的。
我尝试渲染锚点,点击它,然后测试window.location.href
:
test('should navigate to ... when link is clicked', () =>
const getByText = render(<a href="https://test.com">Click Me</a>);
const link = getByText('Click Me');
fireEvent.click(link);
expect(window.location.href).toBe("https://www.test.com/");
);
我希望测试能够通过,但 window.location.href 只是 "http://localhost/"
,这意味着无论出于何种原因它都不会更新。我什至尝试用await wait
包装我的期望,但这也不起作用。我找不到太多关于使用react-testing-library
测试锚点的信息。也许有比我正在做的更好的方法来测试它们。 ????♂️
【问题讨论】:
【参考方案1】:这是我用的:
const linkToTest = screen.getByRole("link", name: /link to test/i )
// I used regex here as a value of name property which ignores casing
expect(linkToTest.getAttribute("href")).toMatchInlineSnapshot();
然后运行测试,toMatchInlineSnapshot
的括号将被您代码中的值填充。
这样的好处是不用硬编码,维护起来会更容易。
例如:它会这样填充:
expect(linkToTest.getAttribute("href")).toMatchInlineSnapshot(`"link/to/somewhere"`);
下一次,假设您将此链接更改为代码库中的其他内容,运行程序会询问您是否要更新,请按u
,它将被更新。 (注意,您需要检查此更新是否正确)。
在Jest Docs了解更多关于内联快照的信息
【讨论】:
【参考方案2】:您可能需要在一个页面上查看多个链接。我发现这些建议非常有用。我做了什么来调整它以检查同一页面上的 5 个链接 -
-
使用
screen()
方法最佳实践查询页面上的链接-更可靠
断言链接在页面上
将链接分配给变量
链接上的调用事件
确保使用 url toHaveAttribute
方法而不是使用窗口对象导航 - 与虚拟 DOM 做出反应,如果您尝试导航到另一个页面,则链接指向 http://localhost/link 而不是测试重定向
test('should navigate to url1 when link is clicked', () =>
const componentName = render(<Component/>)
const url1 = getByText("https://www.test.com/")
expect(ur1).toBeInTheDocument()
screen.userEvent.click(url1);
expect(url1).toHaveAttribute('href', 'https://www.test.com/')
);
【讨论】:
【参考方案3】:简单易行。
试试这个
it('should be a link that have href value to "/login"', () =>
render(<SigningInLink />);
const link = screen.getByRole('link', name: /log in/i );
expect(link.getAttribute('href')).toBe('/login');
);
【讨论】:
【参考方案4】:如果您使用的是screen
,这应该是 RTL 作者的首选方式:
const linkEl = screen.getByRole('link', name: 'Click Me' );
expect(linkEl).toHaveAttribute('href', '...')
类似,无屏幕(名称可以是字符串或正则表达式):
const linkEl = getByRole('link', name: 'Click Me' );
【讨论】:
【参考方案5】:在这种情况下,它可能是公开设计的。但您也可以使用 data-testid 属性。这可以保证您获得 a 标签。我认为这对更复杂的组件有好处。
test('should navigate to ... when link is clicked', () =>
const getByTestId = render(<a data-testid='link' href="https://test.com">Click Me</a>);
expect(getByTestId('link')).toHaveAttribute('href', 'https://test.com');
);
【讨论】:
【参考方案6】:我找到了一个可以帮助其他人的解决方案。 <a>
元素被 React 测试库视为 link
角色。这应该有效:
expect(screen.getByRole('link')).toHaveAttribute('href', 'https://www.test.com');
【讨论】:
这可能是最好的答案,因为在 RTL 文档中它说按角色查询在查询方面具有最高优先级。 About Queries【参考方案7】:Jest 使用 jsdom 来运行它的测试。 jsdom 是模拟浏览器,但它有一些限制。这些限制之一是您无法更改位置。如果您想测试您的链接是否有效,我建议您检查<a>
的href
属性:
expect(screen.getByText('Click Me').closest('a')).toHaveAttribute('href', 'https://www.test.com/')
【讨论】:
我得到TypeError: getByText(...).closest is not a function
任何想法?
我猜getByText
在你的情况下找不到任何东西
我只需要添加 screen
: expect(screen.getByText('Click Me').closest('a')).toHaveAttribute('href', 'https://www.test.com/')
并像魅力一样工作。
我遇到了同样的问题并添加了 import "@testing-library/jest-dom/extend-expect";到文件顶部修复了问题
这不如下面多米尼克的答案,因为搜索closest('a')
,它有点超出了react-testing-library的精神(“你的测试越像你的软件的使用方式,他们能给你的信心就越大") imo。 getByRole('link')
更符合图书馆的精神,因为不需要这样的搜索。即使图书馆的精神本身就是有问题的,哈哈。请注意,我没有投反对票 - 只是说...【参考方案8】:
您可以简单地使用它:
expect(getByText("Click Me").href).toBe("https://www.test.com/")
【讨论】:
这并不能防止有一个 prop href 但没有 的开发错误。考虑动态组件,例如,呈现为链接的按钮。当然,这没有任何意义,但要强制测试失败,您需要验证属性 href 是否正在链接元素中使用。 你需要引用 screen ,但即使这样做你也会得到一个类型错误,因为:TS2339: Property 'href' does not exist on type 'htmlElement' 在反应中,这会将/link
转换为http://localhost/link
,从而导致测试失败。使用toHaveAttribute
可以正常工作。以上是关于如何使用 react-testing-library 测试锚的 href的主要内容,如果未能解决你的问题,请参考以下文章
如何在自动布局中使用约束标识符以及如何使用标识符更改约束? [迅速]
如何使用 AngularJS 的 ng-model 创建一个数组以及如何使用 jquery 提交?