React Intl
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
Nota
Si deseas combinar setupTests con otra configuración, debes consultar
setup
Configuración de Polyfills/Locales para React-Intl
Si estás utilizando React-Intl en tu proyecto y necesitas cargar un locale, tienes dos opciones:
Al usar Node 13 o superior, el soporte para Intl ahora está integrado. La opción predeterminada de ICU (International Components for Unicode) para Node es
full-icu, lo que significa todos los componentes ICU.
Solo necesitas incluir el conjunto de datos ICU que requieras:// test-utils.js
const hasFullICU = () => {
// That's the recommended way to test for ICU support according to Node.js docs
try {
const january = new Date(9e8)
const pt = new Intl.DateTimeFormat('pt', {month: 'long'})
return pt.format(january) === 'janeiro'
} catch (err) {
return false
}
}
export const setupTests = () => {
if (hasFullICU()) {
Intl.NumberFormat.format = new Intl.NumberFormat('pt').format
Intl.DateTimeFormat.format = new Intl.DateTimeFormat('pt').format
} else {
global.Intl = IntlPolyfill
}
}Al usar versiones anteriores de Node, la opción ICU predeterminada es
small-icu, que incluye un subconjunto de datos ICU (normalmente solo el locale inglés).
Si necesitas cargar un locale, tienes dos alternativas:Cargar los Polyfills según el idioma requerido:
// test-utils.js
import IntlPolyfill from 'intl'
import 'intl/locale-data/jsonp/pt'
export const setupTests = () => {
// https://formatjs.io/docs/guides/runtime-requirements/#nodejs
if (global.Intl) {
Intl.NumberFormat = IntlPolyfill.NumberFormat
Intl.DateTimeFormat = IntlPolyfill.DateTimeFormat
} else {
global.Intl = IntlPolyfill
}
}Cargar los ICU en tiempo de ejecución:
Instala el paquete full-icu e inyéctalo en tu entorno de pruebas, puedes hacerlo estableciendoNODE_ICU_DATAantes de ejecutar Jest:NODE_ICU_DATA=node_modules/full-icu jest. Esto te dará soporte full-icu como se muestra en la opción 1.
Creación de una función render personalizada
Para probar nuestro componente traducido, podemos crear una función render personalizada usando
la opción wrapper como se explica en la página de
configuración.
Nuestra función render personalizada podría verse así:
// test-utils.js
import React from 'react'
import {render as rtlRender} from '@testing-library/react'
import {IntlProvider} from 'react-intl'
function render(ui, {locale = 'pt', ...renderOptions} = {}) {
function Wrapper({children}) {
return <IntlProvider locale={locale}>{children}</IntlProvider>
}
return rtlRender(ui, {wrapper: Wrapper, ...renderOptions})
}
// re-export everything
export * from '@testing-library/react'
// override render method
export {render}
Ejemplo completo
import React from 'react'
import '@testing-library/jest-dom'
// We're importing from our own created test-utils and not RTL's
import {render, screen, setupTests} from '../test-utils.js'
import {FormattedDate} from 'react-intl'
const FormatDateView = () => {
return (
<div data-testid="date-display">
<FormattedDate
value="2019-03-11"
timeZone="utc"
day="2-digit"
month="2-digit"
year="numeric"
/>
</div>
)
}
setupTests()
test('it should render FormattedDate and have a formatted pt date', () => {
render(<FormatDateView />)
expect(screen.getByTestId('date-display')).toHaveTextContent('11/03/2019')
})
Estrategia de pruebas para componentes traducidos
Al probar un componente traducido, pueden existir diferentes enfoques para lograr la cobertura deseada, donde el objetivo principal debe ser permitir probar el componente de manera que simule el comportamiento del usuario tanto como sea posible.
| Approach | Pros | Cons |
|---|---|---|
| Use strings from the default language | Test is easy to read, and asserts expected default output. If you have variables in your strings, you can test that they work properly with correct output. | 1. Strings hardcoded into tests mean you have to update both tests and code for any copy changes. 2. If multiple elements have the same string/substring text, find-and-replace may be hard to use reliably. |
| Mock the translation library | If your library is difficult to use in the test environment, you can mock it so it is easier. For example, you can add the message ID as a data-attribute to the text so you can query by that. | Test code deviates from what runs in production. Tests may assert about message IDs but not enough about content, so errors are possible. |
| Use translation library in tests | Decouples strings from tests, so you can update the message files in one place without worrying about breaking tests. Can run tests in another language or multiple languages. const buttonText = getNodeText(<FormattedMessage id="buttonText" defaultMessage="Hello Button" />); | Overhead - it takes more lines of code to write the test, and you need to know the variables and message IDs to create the right strings. It's not obvious what the text actually is when you read the test code, making maintaining it harder. |
| Use translation library + inline snapshots | Same as above, but by adding an inline snapshot of the string, you can read the test code and see what strings are in use, but easily update them with jest --updateSnapshot if the messages change. expect(buttonText).toMatchInlineSnapshot("'My button text'") | Tests are longer because of the extra lines. You can wrap up some of the translation-related code into a helper function to make it a little more inline-able and avoid repeating yourself, but you still need to know the message IDs and variables inside the test. |