DEV Community

noire.munich
noire.munich

Posted on

Testing with react-i18next in RedwoodJS

This post assumes you've already fiddled with RedwoodJS and are looking further into it for something you'd show the world. It is about testing & translation, hence the title. If you have experience with both topics, the article might not be very relevant to you, instead I'd suggest checking out RedwoodJS.


Context

A while back as I was trying to set up my current project, I tried to follow the Redwood Way ( no definitive specification on that one as of yet, AFAIK ) and implement frontend tests. I had never worked with frontend tests before and soon enough I stumbled onto performance issues. The ticket doesn't show the real story, but what happened was that I had errors thrown and no way to gather enough information to understand what was going on - and having to wait 90 seconds for any file update quickly became an obstacle I couldn't deal with.

I left the frontend tests aside until @jtoar pinged me on the original issue this week. v0.42 ships with improvements on testing, I had to try it and see where we were at now.

To do so I met my following problem: tests were still failing, but in 10s, which is way better and let me investigate a bit more the core of my problem - translation.


Hands on

If your application supports translation, you may find yourself with many components relying on i18n 's ( or your library of choice to handle that ) functions or components. Those may impair your tests if you do not use proper mocks.
Fortunately this is rather straightforward. This example works with react-i18next.
First, let's define a component that will use the library. Let's KISS this:

import { useTranslation } from 'react-i18next'  

const Input = ({ pointer, name }) => {  
  const { t } = useTranslation()  

  return (  
    <div>  
 <label>{t(pointer)}</label>  
 <input name={name} />  
 </div>  
 )  
}  

export default Input
Enter fullscreen mode Exit fullscreen mode

Second, we need to define a test configuration for the library:

# src/configuration/i18nForTests.ts
import i18n from 'i18next'  

i18n      
.init({  
    lng: 'en',  
    fallbackLng: 'en',  

    // have a common namespace used around the full app    
ns: ['site'],  
    defaultNS: 'site',  

    debug: false,  

    interpolation: {  
      escapeValue: false, // not needed for react!!    
},  

    resources: { fr: { site: {}  } },  
  })  

export default i18n
Enter fullscreen mode Exit fullscreen mode

Finally, we can run some tests:

import 'src/configuration/i18nForTests'  
import { fireEvent, render, screen } from '@redwoodjs/testing'  
import Input from './Input'  

jest.mock('react-i18next', () => ({  
  // this mock makes sure any components using the translate hook can use it without a warning being shown  
 useTranslation: () => {  
    return {  
      t: (str) => str,  
      i18n: {  
        changeLanguage: () => new Promise(() => {}),  
      },  
    }  
  },  
}))  

describe('UI/Input', function () {  
  it('Renders successfully', function () {  
    render(<Input name={'someInput'} pointer={'site:input.text'} />)  

    expect(screen.getByRole('textbox')).toBeInstanceOf(HTMLInputElement)  
  })  
})
Enter fullscreen mode Exit fullscreen mode

That should do the trick. 10s of success, now!

There's a debug prop in the configuration object for i18n, if set to true you'll get information about missing keys. I haven't played with that, but if I had time, that could be valuable.

Happy coding.


Notes

RedwoodJS let's you setup translation with an out of the box cli command:

yarn rw setup i18n
Enter fullscreen mode Exit fullscreen mode

If you pickup RedwoodJS and don't have strong preferences on translation libs, there's a solution for you.

Top comments (0)