【问题标题】:How to test anchor's href with react-testing-library如何使用 react-testing-library 测试锚的 href
【发布时间】: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 测试锚点的信息。也许有比我正在做的更好的方法来测试它们。 ????‍♂️

【问题讨论】:

    标签: reactjs jestjs anchor href 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 个链接 -

      1. 使用screen()方法最佳实践查询页面上的链接-更可靠
      2. 断言链接在页面上
      3. 将链接分配给变量
      4. 链接上的调用事件
      5. 确保使用 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】:

              我找到了一个可以帮助其他人的解决方案。 &lt;a&gt; 元素被 React 测试库视为 link 角色。这应该有效:

              expect(screen.getByRole('link')).toHaveAttribute('href', 'https://www.test.com');
              

              【讨论】:

              • 这可能是最好的答案,因为在 RTL 文档中它说按角色查询在查询方面具有最高优先级。 About Queries
              【解决方案7】:

              Jest 使用 jsdom 来运行它的测试。 jsdom 是模拟浏览器,但它有一些限制。这些限制之一是您无法更改位置。如果您想测试您的链接是否有效,我建议您检查&lt;a&gt;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 可以正常工作。
              猜你喜欢
              • 2019-08-29
              • 2021-11-30
              • 2019-05-21
              • 2019-11-11
              • 2019-10-30
              • 2021-02-11
              • 2022-08-04
              • 2023-04-04
              • 1970-01-01
              相关资源
              最近更新 更多