【问题标题】:How to trigger onClose for react ui Menu with react-testing-libray?如何使用 react-testing-library 触发反应 ui 菜单的 onClose?
【发布时间】:2019-07-28 13:51:31
【问题描述】:

我正在使用带有 onClose 属性的 react-testing-library 测试 react Material UI Menu 组件,该属性在菜单失去焦点时触发。即使我向菜单外的组件添加点击或将焦点添加到外部的输入元素,我也无法触发此状态。

const UserMenu: React.FunctionComponent<UserMenuProps> = ({ className }) => {
  const signedIn = useAuthState(selectors => selectors.SignedIn);
  const username = useAuthState(selectors => selectors.Username);
  const messages = useMapState((state: AppRootState) => state.app.messages);
  const signOut = useSignOut();

  const [open, updateOpenStatus] = useState(false);
  const anchorRef = useRef(null);

  if (!signedIn) {
    return <div data-testid="user-menu" className={className}>
      <LinkButton to={ROUTES.SignIn.link()}>{messages.SignIn.Title}</LinkButton>
      <LinkButton to={ROUTES.SignUp.link()}>{messages.SignUp.Title}</LinkButton>
      <LinkButton to={ROUTES.ConfirmSignUp.link()}>{messages.ConfirmSignUp.Title}</LinkButton>
    </div>;
  }

  return <div data-testid="user-menu" className={className}>
    <Grid container direction="row" alignItems="center">
      <Typography noWrap variant="subtitle2">
        <span id="username" className="bold">{username}</span>
      </Typography>
      <IconButton id="menu-toggle" buttonRef={anchorRef} onClick={() => updateOpenStatus(true)}>
        <AccountCircle/>
      </IconButton>
      <Menu
        anchorEl={anchorRef.current}
        anchorOrigin={{
          vertical: 'top',
          horizontal: 'right'
        }}
        transformOrigin={{
          vertical: 'top',
          horizontal: 'right'
        }}
        open={open}
        onClose={() => updateOpenStatus(false)}
      >
        <MenuItem id="sign-out" onClick={() => { updateOpenStatus(false); signOut(); }}>{messages.SignOut.Action}</MenuItem>
      </Menu>
    </Grid>
  </div>;
};

测试代码

    it('should open and close menu', async () => {
      const { getByTestId } = render(<><UserMenu/>
        <input data-testid="other"/>
      </>, { state });

      fireEvent.click(getByTestId('menu-toggle'));

      expect(MockMenu).toHaveBeenLastCalledWith(expect.objectContaining({ open: true }), {});

      fireEvent.focus(getByTestId('other'));

      expect(MockMenu).toHaveBeenLastCalledWith(expect.objectContaining({ open: false }), {});
    });

我也试过fireEvent.click(getByTestId('other'));,但没有成功。

这个酶的question 有一个使用tree.find(Menu).simulate("close"); 的解决方案,但我认为react-testing-library 不可能。

【问题讨论】:

  • 不确定是否相关,但您有getByTestId('menu-toggle'),但您没有任何data-testid="menu-toggle"

标签: reactjs unit-testing material-ui react-testing-library


【解决方案1】:

您可以通过单击菜单生成的背景来触发关闭。我发现最简单的方法是通过 @testing-librarygetByRole('presentation') 方法选择背景。

测试代码:

it('should open and close the menu', () => {
  const { getByTestId, getByRole } = render(<UserMenu />);

  fireEvent.click(getByTestId('menu-toggle'));

  // Get the backdrop, then get the firstChild because this is where the event listener is attached
  fireEvent.click(getByRole('presentation').firstChild));

  expect(MockMenu).toHaveBeenLastCalledWith(expect.objectContaining({ open: false }), {});
});

【讨论】:

  • 抱歉,但按角色“演示文稿”搜索似乎没有返回任何内容Error: Unable to find an element by [role=presentation]
  • @kossmoboleat 如果你使用 RTL renderResult 中的debug,你有任何类型的背景吗?
  • MockMenu 声明在哪里?
  • 我最初是从作者那里得到的。我认为这是对他们回调的模拟,但可能需要调整设置。通常,您只需测试单击背景时是否调用了关闭回调,或者该组件不再可见(或两者兼而有之)。在这种情况下,可能是:expect(queryByRole('presentation')).toBeNull()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-17
  • 1970-01-01
  • 2019-03-10
  • 2020-03-15
  • 1970-01-01
  • 2019-08-29
  • 2019-05-23
相关资源
最近更新 更多