Skip to main content

React Intl

Nota

Se quiseres combinar a setupTests com uma outra configuração deverias verificar a setup.

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:

  1. 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
    }
    }
  2. 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:

    1. 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
      }
      }
    2. Carregar os ICUs em tempo de execução: Instale o pacote full-icu e injete-o no teu ambiente de teste, podes fazer isto definindo NODE_ICU_DATA antes da chamada de Jest: NODE_ICU_DATA=node_modules/full-icu jest. Fazendo isto dar-te-ás o suporte full-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:

AbordagemPósContras
Usar sequências de caracteres da linguagem padrãoO 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çãoSe 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 testesSepara 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 linhaO 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.