React Intl
Nota
Se quiseres combinar a
setupTests
com uma outra configuração deverias verificar asetup
.
Configurando Polyfills
de React-Intl
ou Locais
Se estiveres a usar a React-Intl
no teu projeto, e precisas de carregar
uma localização, tens duas opções:
Quando estiveres a usar a Node 13 e superior, o suporte de
Intl
está agora fora da caixa. A opção padrão de Componentes Internacionais para Unicode (ICU, sigla em Inglês) para Node éfull-icu
significando todos ICUs. Tudo o que precisas de fazer é fixar o conjunto de dados de ICU precisas de:// test-utils.js
const hasFullICU = () => {
// É a maneira recomendada para testar pelo suporte de ICU de acordo com a documentação da Node.js
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
}
}Quando estiveres a usar a Node com versões anteriores, a opção padrão de ICU é
small-icu
significando que inclui um subconjunto de dados de ICU (normalmente apenas o local Inglês). Se precisares de carregar um local tens duas opções:Carregar os
Polyfills
de acordo com a linguagem:// 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
}
}Carregar os ICUs em tempo de execução: Instale o pacote
full-icu
e injete-o no teu ambiente de teste, podes fazer isto definindoNODE_ICU_DATA
antes da chamada de Jest:NODE_ICU_DATA=node_modules/full-icu jest
. Fazendo isto dar-te-ás o suportefull-icu
como mostrado na opção 1.
Criando um função interpretadora personalizada
Para testar o nosso componente traduzido podemos criar uma função render
personalizada usando a opção wrapper
conforme explicado na página de
configuração. A nossa função render
personalizada pode parecer-se com esta:
// 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-exporta tudo
export * from '@testing-library/react'
// sobrepõe o método `render`
export {render}
Um exemplo completo
import React from 'react'
import '@testing-library/jest-dom'
// Estamos a importar a partir da nossa própria `test-utils` e
// não da RTL
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')
})
Estratégia de testagem de componentes traduzidos
Quando estiveres a testar um componente traduzido podem existir diferentes abordagens para alcançar a cobertura desejada, onde o objetivo definido deveria ser permitir testar o componente de uma maneira que simulará o comportamento do utilizador o máximo possível:
Abordagem | Pós | Contras | |||
---|---|---|---|---|---|
Usar sequências de caracteres da linguagem padrão | O teste é fácil de ler, e afirma a saída padrão esperada. Se tens variáveis nas tuas sequências de caracteres, podes testar se funcionam apropriadamente com a saída correta. | 1. As sequências de caracteres escritas manualmente nos testes significa que tens de atualizar ambos testes e código para quaisquer mudanças da cópia. 2. Se vários elementos têm a mesmo texto de sequência de caracteres ou subsequência de caracteres, encontrar e substituir pode ser difícil de usar com confiança. | Imitar a biblioteca de tradução | Se a tua biblioteca for difícil de usar no ambiente de teste, podes imitá-la assim é mais fácil. Por exemplo, podes adicionar um identificador de mensagem de acordo com atributo de dado para o texto assim podes consultar por esta. | Testar o código afasta-se do que executa em produção. Os testes podem afirmar sobre os identificadores da mensagem mas não o suficiente sobre o conteúdo, assim erros são possíveis. |
Usar a biblioteca de tradução nos testes | Separa as sequências de caracteres dos testes, assim podes atualizar os ficheiros da mensagem em um lugar sem a preocupação de quebrar os testes. Podes executar os testes em uma outra linguagem ou várias linguagens. const buttonText = getNodeText(<FormattedMessage id="buttonText" defaultMessage="Hello Button" />); | Despesa geral - custa mais linhas de código para escrever o teste, e precisas de conhecer as variáveis e identificadores da mensagem para criar as sequências de caracteres corretas. Não é óbvio o que o texto realmente é quando lês o código de teste, tornando mais difícil de mantê-lo. | |||
Usar a biblioteca de tradução + fotografia em linha | O mesmo que o de cima, mas adicionado uma fotografia em linha da sequência de caracteres, podes ler o código de teste e ver quais sequências de caracteres estão em uso, mas facilmente atualizá-los com jest -u se as mensagens mudarem. expect(buttonText).toMatchInlineSnapshot("'My button text'") | Os testes são mais longos por causa das linhas adicionais. Tu podes embrulhar algum do código relacionado com a tradução em uma função auxiliar para torná-lo um pouco mais em linha e evitar repetires-te, mas ainda precisas de conhecer os identificadores da mensagem e as variáveis dentro do teste. |