Testing¶
Warning
This is an incomplete draft of a guide.
Components using <Trans> or withI18n()
require access to the context of <I18nProvider>. This is not available when mounting single components in Enzyme. These helper functions aim to address that and wrap a valid, context around them.
Adapted from this gist.
import React from 'react'
import { shape, object } from 'prop-types'
import { mount, shallow } from 'enzyme'
import { I18nProvider } from '@lingui/react'
// Create the I18nProvider to retrieve context for wrapping around.
const language = 'de-DE'
const intlProvider = new I18nProvider({
language,
catalogs: {
[language]: {}
}
}, {})
const {
linguiPublisher: {
i18n: originalI18n
}
} = intlProvider.getChildContext()
// You customize the i18n object here:
const i18n = {
...originalI18n,
_: key => key // provide _ macro, for just passing down the key
}
/**
* When using Lingui `withI18n` on components, props.i18n is required.
*/
function nodeWithI18nProp(node) {
return React.cloneElement(node, { i18n })
}
/*
* Methods to use
*/
export function shallowWithIntl(node, { context } = {}) {
return shallow(
nodeWithI18nProp(node),
{
context: Object.assign({}, context, { i18n })
}
)
}
export function mountWithIntl(node, { context, childContextTypes } = {}) {
const newContext = Object.assign({}, context, { linguiPublisher: { i18n } })
/*
* I18nProvider sets the linguiPublisher in the context for withI18n to get
* the i18n object from.
*/
const newChildContextTypes = Object.assign({},
{
linguiPublisher: shape({
i18n: object.isRequired
}).isRequired
},
childContextTypes
)
return mount(
nodeWithI18nProp(node),
{
context: newContext,
childContextTypes: newChildContextTypes
}
)
}
Usage:
import { mountWithIntl } from 'enzyme-test-helper.js'
const wrapper = mountWithIntl(
<OurComponent />
);
expect(wrapper.state('prop')).to.equal('value')
Snapshot testing¶
Snapshot testing is fast and convenient way to ensure you app doesn’t change unexpectedly. However, components are serialized with all props, so even simple translation:
<Trans>Today is <DateFormat value={now} /></Trans>
has a very long and hard to read snapshot:
<Trans
i18n={
I18n {
_activeLanguageData: Object {
plurals: [Function],
},
_activeMessages: Object {},
_catalogs: Object {
en: Object {
languageData: Object {},
messages: Object {},
},
},
_dev: Object {
compile: [Function],
loadLanguageData: [Function],
},
_language: en,
_locales: undefined,
plural: [Function],
select: [Function],
selectOrdinal: [Function],
t: [Function],
}
}
i18nHash={null}
id=Today is {now,date}
values={
Object {
now: 2017-04-05T11:14:00.000Z,
}
}
>
<Render
value=Today is 4/5/2017
>
Today is 4/5/2017
</Render>
</Trans>
In such case we might want to test just an HTML output. jest-serializer-html indents and formats HTML in snapshot making it easier to diff. Add it to Jest config:
{
"snapshotSerializers": [
"jest-serializer-html"
]
}
Instead of serializing element wrapper, serialize HTMl instead:
expect(mount(<Trans>Today is <DateFormat value={now} /></Trans>).html())
.toMatchSnapshot()
The final snapshot is shorter and easy to review:
<div>Today is 4/5/2017</div>