Reputation: 895
I am implementing internationalization in a react application with the react-intl library. The language can be triggered in different components, so I used the pubsub-js library to publish an event each time the language is changed, and subscrib to this event in my central App Component, which then switches the locale and messages which are displayed in the whole application.
My question concerns writing tests with jest and enzyme which would trigger the language change and have my App component updated with the language, so I can assert that the state variables dealing with the locale are correctly updated. Is it possible to trigger such events, or am I on a wrong path here? My code is listed below
//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');
});
});
Upvotes: 3
Views: 3550
Reputation: 111022
So you have to mock the 'pubsub-js'
module like this:
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()
});
});
Upvotes: 1