Как вызвать событие Pubsub.js в шутливом тесте для react.js

Я реализую интернационализацию в реагирующем приложении с библиотекой react-intl. Язык может запускаться в разных компонентах, поэтому я использовал библиотеку pubsub-js для публикации события каждый раз. когда язык меняется, и подпишитесь на это событие в моем центральном компоненте приложения, который затем переключает язык и сообщения, отображаемые во всем приложении.

Мой вопрос касается написания тестов с помощью jest и enzyme, который вызовет смену языка и обновит компонент моего приложения с помощью языка, поэтому я могу утверждать, что переменные состояния, связанные с локалью, обновлены правильно. Можно ли инициировать такие события, или я на неправильном пути? Мой код указан ниже

//Relevant parts of the app component


class App extends Component {
  constructor(props) {
    super(props);
    this.localeStore = new LocaleStore();
    this.state = {
      locale: this.localeStore.locale(),
      messages: this.localeStore.messages()
    };
  }

  componentDidMount() {
    PubSub.subscribe(LocaleEvent.change, (event, locale) => {
      this.setState({locale: locale.code, messages: locale.messages})
    });
  }

  componentWillUnmount() {
    PubSub.unsubscribe(LocaleEvent.change);
  }

  render() {
    return (
      <IntlProvider key={ this.state.locale } locale={ this.state.locale } messages={ this.state.messages }>
        <div>
          ...
        </div>
      </IntlProvider>
    );
  }
}

// App.test.js

describe('App', () => {
  it('renders without crashing', () => {
    const div = document.createElement('div');
    mount(<App />);
  });

  // This test fails, because the event is not published and the state does not change
  it('correctly switches the language when the language change event is triggered', () => {
    let app = mount(<App />);

    PubSub.publish('locale.change', {code: 'en', messages: {}});

    expect(app.state().locale).toEqual('en');
  });
});

person Awemo    schedule 17.05.2017    source источник
comment
Компонент PubSub импортирован в ваш модуль или происходит из глобального пространства имен?   -  person Andreas Köberle    schedule 17.05.2017
comment
Кроме того, это звучит как главный кандидат на Redux.   -  person Patrick    schedule 17.05.2017
comment
Он импортируется в компоненты, которые его используют.   -  person Awemo    schedule 17.05.2017
comment
Хорошо, тогда я бы просто издевался над импортом, напишу ответ на это.   -  person Andreas Köberle    schedule 17.05.2017


Ответы (1)


Итак, вам нужно издеваться над модулем 'pubsub-js' следующим образом:

import PubSub from 'pubsub-js'

jest.mock('pubsub-js', ()=>({
  subscribe:(e, fn) => fn({}, {code: 'de', messages:'someMessages'}),
  unsubscribe: jest.fn()
}))

describe('App', () => {

  it('correctly switches the language when the language change event is triggered', () => {
    const app = mount(<App />)
    expect(app.state().locale).toEqual('de');
    app.unmount()
    expect(PubSub.unsubscribe).toHaveBeenCalled()
  });
});
person Andreas Köberle    schedule 17.05.2017
comment
Когда я пробую это решение, я получаю следующую ошибку: ReferenceError: PubSub не определен. - person Awemo; 18.05.2017
comment
Как вы импортируете его в свой компонент? - person Andreas Köberle; 18.05.2017
comment
Как вы делали выше: import PubSub from 'pubsub-js';. - person Awemo; 18.05.2017
comment
Но как можно получить ошибку тогда, когда он работает на вашем компоненте, странно. Можете ли вы удалить макет и посмотреть, что происходит? - person Andreas Köberle; 18.05.2017
comment
Сотрите предыдущую ошибку, я, должно быть, что-то упустил. Теперь я получаю следующую ошибку: TypeError: Cannot read property 'code' of undefined - person Awemo; 18.05.2017
comment
Арг, есть небольшая ошибка в моем примере, исправлю. - person Andreas Köberle; 18.05.2017