首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在react-testing中的fireEvent.click之后,将radio的aria-checked属性设置为true

在react-testing中的fireEvent.click之后,将radio的aria-checked属性设置为true
EN

Stack Overflow用户
提问于 2019-06-28 15:00:04
回答 1查看 2.5K关注 0票数 0

我想在fireEvent.click之后将radiobutton的aria-checked属性设置为true。我不想通过setAttribute来做这件事,而是通过onclick。

我尝试了下面的代码来测试我的组件。

Radiobutton.js

代码语言:javascript
复制
function Radiobutton(props) {
  const { label, onClick, onKeyPress, isChecked } = props;

  return (
    <div
      className="radiobutton"
      role="radio"
      onClick={onClick}
      onKeyDown={onKeyPress}
      aria-checked={isChecked}
      tabIndex={0}
      value={label}
    >
      <span className="radiobutton__label">{label}</span>
    </div>
  );
} 

Radiobutton.test.jsx

代码语言:javascript
复制
test("radiobuttons must use click", () => {
  const handleChange = jest.fn();
  const { container } = render(
    <Radiobutton onClick={handleChange} isChecked={false} label="Dummy Radio" />
  );
  const radiobtn = getByRole(container, "radio");
  fireEvent.click(radiobtn);
  expect(handleChange).toHaveBeenCalledTimes(1);
  expect(radiobtn.getAttribute("aria-checked")).toBe("true");

});

我可以调用handleChange函数,但无法更改aria-checked的值。我得到了以下错误。

代码语言:javascript
复制
    expect(received).toBe(expected) // Object.is equality

    Expected: "true"
    Received: "false"

      30 |   expect(handleChange).toHaveBeenCalledTimes(1);
    > 31 |   expect(radiobtn.getAttribute("aria-checked")).toBe("true");
         |                                                 ^
      32 |   console.log(prettyDOM(radiobtn));
      33 | });

      at Object.toBe (src/__tests__/radiobutton.test.jsx:31:49)

我是测试新手。任何帮助都将不胜感激。提前谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-28 18:51:04

根据组件的代码处理更改发生在父元素上。要在测试中模拟此行为,需要在调用handleChange后更新isChecked属性。

对于maintainer's comment来说,实现这一目标的方法是使用不同的道具将相同的元素重新渲染到相同的容器中:

代码语言:javascript
复制
test("radiobuttons must use click", () => {
  const handleChange = jest.fn();
  const { container } = render(
    <Radiobutton onClick={handleChange} isChecked={false} label="Dummy Radio" />
  );
  const radiobtn = getByRole(container, "radio");
  fireEvent.click(radiobtn);
  expect(handleChange).toHaveBeenCalledTimes(1);
  render(<Radiobutton onClick={handleChange} isChecked={true} label="Dummy Radio" />, { container });
  expect(radiobtn.getAttribute("aria-checked")).toBe("true");
});

此外,您可能会将重新呈现逻辑放在handleChange.mockImplementation中,但我认为这会使测试用例更难阅读:

代码语言:javascript
复制
test("radiobuttons must use click", () => {
  let isChecked = false;
  const handleChange = jest.fn();
  const { container } = render(
    <Radiobutton onClick={handleChange} isChecked={false} label="Dummy Radio" />
  );
  handleChange.mockImplementation(() => {
    isChecked = !isChecked;
    render(<Radiobutton onClick={handleChange} isChecked={isChecked} label="Dummy Radio" />, { container });
  });
  const radiobtn = getByRole(container, "radio");
  fireEvent.click(radiobtn);
  expect(handleChange).toHaveBeenCalledTimes(1);
  expect(radiobtn.getAttribute("aria-checked")).toBe("true");
});

另一个缺点是handleChange逻辑应该在父组件中的某个地方,所以你更愿意测试自己的模拟,而不是测试你的应用程序。

对我来说,它看起来真的很混乱,并且不会给你提供任何额外的价值,因为在现实世界中,它将取决于父组件是否在onClick之后更新isChecked

因此,我建议您将测试用例一分为二。首先检查checks是否调用onClick处理程序。并单独检查isChecked={true}是否提供aria-checked。如果让第三方检查isChecked={false}是否没有注入aria-checked属性,可能会更好。

代码语言:javascript
复制
test('provides aria-checked if isChecked is truly`, () => {
  const { container } = render(<Radiobutton isChecked={true} />);
  const radiobtn = getByRole(container, "radio");
  expect(radiobtn.getAttribute("aria-checked")).toBe("true");
});
test('does not provide aria-checked if isChecked is falsy`, () => {
  const { container } = render(<Radiobutton />);
  const radiobtn = getByRole(container, "radio");
  expect(radiobtn.getAttribute("aria-checked")).not.toBe("true");
});
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56802306

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档