Не могу закрыть модальное меню через энзим - PullRequest
0 голосов
/ 18 декабря 2018

проблема довольно проста.У меня есть меню Material-UI, которое я хотел бы проверить соответствующим образом (через пользователя, щелкающего за пределами меню).

Это оказалось довольно сложным делом.Вот компонент (извлеченный прямо из документов ):

class App extends React.Component {
  state = {
    anchorEl: null
  };

  handleClick = event => {
    this.setState({ anchorEl: event.currentTarget });
  };

  handleClose = () => {
    this.setState({ anchorEl: null });
  };

  render() {
    const { anchorEl } = this.state;

    return (
      <div>
        <Typography variant="body1"> Click Me</Typography>
        <Button
          aria-owns={anchorEl ? "simple-menu" : undefined}
          aria-haspopup="true"
          onClick={this.handleClick}
        >
          Open Menu
        </Button>
        <Menu
          id="simple-menu"
          anchorEl={anchorEl}
          open={Boolean(anchorEl)}
          onClose={this.handleClose}
        >
          <MenuItem onClick={this.handleClose}>Profile</MenuItem>
          <MenuItem onClick={this.handleClose}>My account</MenuItem>
          <MenuItem onClick={this.handleClose}>Logout</MenuItem>
        </Menu>
      </div>
    );
  }
}

И тесты:

const props = {
  classes: {}
};

describe("test", () => {
  it("closes the menu", () => {
    const wrapper = mount(<App {...props} />);
    wrapper.find(Button).simulate("click");
    expect(wrapper.find(Menu).prop("open")).toBe(true);
    wrapper.find(Typography).simulate("click");
    expect(wrapper.find(Menu).prop("open")).toBe(false);
    wrapper.unmount();
  });

  it("closes the menu a different way", () => {
    const outerNode = document.createElement("div");
    outerNode.setAttribute("id", "root-node");
    document.body.appendChild(outerNode);
    const wrapper = mount(<App {...props} />, {
      attachTo: outerNode
    });
    wrapper.find(Button).simulate("click");
    expect(wrapper.find(Menu).prop("open")).toBe(true);
    outerNode.click();
    expect(wrapper.find(Menu).prop("open")).toBe(false);
    wrapper.unmount();
  });

  it("closes the menu yet a different way", () => {
    const eventMap = {};
    window.addEventListener = jest.fn((event, cb) => {
      eventMap[event] = cb;
    });
    const wrapper = mount(<App {...props} />);
    wrapper.find(Button).simulate("click");
    expect(wrapper.find(Menu).prop("open")).toBe(true);
    wrapper.find(Typography).simulate("click");
    eventMap.click();
    expect(wrapper.find(Menu).prop("open")).toBe(false);
    wrapper.unmount();
  });
});

К сожалению, ни один из этих тестов не работает.Я занимался копанием и наткнулся на этот пост , который связывает эту проблему с github , откуда появились решения и третьи подходы, однако я не могу заставить работать ни один из них.

Я создал CodeSandbox с приведенным ниже кодом для любых щедрых душ, которые хотят помочь.

Edit n3n96op120

1 Ответ

0 голосов
/ 18 декабря 2018

Это может быть потому, что элементы не присутствуют сразу после щелчка.

Можете ли вы попробовать - фермент-асинхронные помощники,

await waitForElement (обертка, Меню);

Редактировать:

После изучения метода имитации () и компонента меню, мои выводы следующие:

  • имитация («щелчок»)внутренне ищет пропозицию onClick для компонента, который вы моделируете, и вызывает этот метод, если он там есть, иначе он ничего не будет делать.В вашем случае в Typography нет обработчика onClick, поэтому он ничего не будет делать.Даже если она есть, она вызовет функцию, которую вы передали, а не фактическую внутреннюю реализацию Menu, где оно закрывается.
  • Меню внутренне с использованием компонента Backdrop, который имеет метод onClick и закрывает меню при нажатииснаружи.

Решение для вашей проблемы будет:

   wrapper.find(Backdrop).simulate("click");

, а также импорт:

import { Button, Menu, Typography, Backdrop } from "@material-ui/core";

Вы можете найти работающий пример здесь: https://codesandbox.io/s/vyon4kvjpy

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...