Skip to content

Instantly share code, notes, and snippets.

@maniax89
Created July 27, 2016 20:52
Show Gist options
  • Save maniax89/62bddbfeefa2e368d37e7f3a9270bd6f to your computer and use it in GitHub Desktop.
Save maniax89/62bddbfeefa2e368d37e7f3a9270bd6f to your computer and use it in GitHub Desktop.
React-Intl with Enzyme
import React from 'react';
import messages from './messages.js';
import { Link } from 'react-router';
import {FormattedMessage, injectIntl, intlShape} from 'react-intl';
class Home extends React.Component {
render() {
const t = this.props.intl.formatMessage;
return (
<div>
<header>
<FormattedMessage {...messages.header}
values={{
link: <Link to="/">
{t(messages.home_link)}
</Link>
}}
/>
</header>
</div>
);
}
}
Home.propTypes = {
intl: intlShape.isRequired
};
export default injectIntl(Home);
import React from 'react';
import { shallowWithIntl } from '../helpers/intl-enzyme-test-helper.js';
import { expect } from 'chai';
import Home from '__main_dir/components/views/Home/Home';
const wrapper = shallowWithIntl(<Home/>);
describe('The home page',function () {
it('should return the home page text', function () {
const headerText = wrapper.render().text();
expect(headerText).to.contain('The home page');
});
});
/**
* Components using the react-intl module require access to the intl context.
* This is not available when mounting single components in Enzyme.
* These helper functions aim to address that and wrap a valid,
* English-locale intl context around them.
*/
import React from 'react';
import { IntlProvider, intlShape } from 'react-intl';
import { mount, shallow } from 'enzyme';
import messages from '../../public/i18n/en.json';
// Create the IntlProvider to retrieve context for wrapping around.
const intlProvider = new IntlProvider({ locale: 'en', messages }, {});
const { intl } = intlProvider.getChildContext();
/**
* When using React-Intl `injectIntl` on components, props.intl is required.
*/
function nodeWithIntlProp(node) {
return React.cloneElement(node, { intl });
}
export function shallowWithIntl(node) {
return shallow(nodeWithIntlProp(node), { context: { intl } });
}
export function mountWithIntl(node) {
return mount(nodeWithIntlProp(node), {
context: { intl },
childContextTypes: { intl: intlShape }
});
}
import {defineMessages} from 'react-intl';
const messages = defineMessages({
header :{
id: 'home.header',
defaultMessage: 'The {link} page',
description: 'header text displayed at the top of the page'
},
home_link: {
id: 'home.home_link',
defaultMessage: 'home',
description: 'link text located in the home.header message'
}
});
export default messages;
@jeantimex
Copy link

Do you see this error? Error: Warning: Failed prop type: Required prop `intl` was not specified in `Home`

@larsha
Copy link

larsha commented Aug 2, 2017

I'm seeing similar issues: Warning: Failed prop type: The prop 'intl' is marked as required in 'Home', but its value is 'undefined'. when using this snippet. Did you manage to solve your issue?

@acanimal
Copy link

I'm using this module enzyme-react-intl that does the same and I have the same issue.

My component is a bit more complex than the example and is using injectIntl and have intl: intlShape.isRequired as a property, which I suspect is what generates the warning.

The workaround (I don't like it) to avoid the warning is removing the isRequied.

@alexander-elgin
Copy link

alexander-elgin commented Jun 20, 2018

Is there any update? I have the same issue (not only with shallowWithIntl but also with mountWithIntl). Please, note that for me the test is passed successfully i.e. the intl prop is set (else there was an exception and the test was failed). It seems that the intl prop is undefined at some moment before rendering.

@alexander-elgin
Copy link

I found a way to avoid the warning in the unit testing environment. There is another way to get a translation string. See my gist

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment