Skip to main content

Testing

FrontHub already brings all the test environments set up and ready to develop. The front-hub-commons dependency brings Jest and Testing Library React as default test runners.

When you create a new app with front-hub-cli the created App comes with a Welcome component. This component comes with a test boilerplate file (Welcome.test.js).

Welcome.test.js
import { render, screen } from '@testing-library/react'
import Welcome from './Welcome'

it('should render title', () => {
render(<Welcome />)

expect(screen.getByRole('heading')).toBeInTheDocument()
})

Testing localization

FrontHub brings the renderWithTranslation utility function. This allows us to test components using react-i18next. See the example below:

import { screen } from '@testing-library/react'
import {
instanceMock,
renderWithTranslation,
} from '@resultadosdigitais/front-hub/react/jest'
import MyComponent from './MyComponent'
import translation from './locales/pt-BR.json'

describe('when rendering my component', () => {
it('should show the hello message', async () => {
await renderWithTranslation(instanceMock(<MyComponent />, translation)

expect(screen.getByText('Olá!')).toBeInTheDocument()
})
})

Caveats

If your micro frontend wasn't created by using the front-hub-cli, you'll need to create a setup test file.

There are two different ways to create the setup test file.

Application created with Create React App

If your application was created with Create React App you'll need to create a setupTests.js file in the micro frontend folder, and call the setup method from the FrontHub as shown below.

setupTests.js
import '@testing-library/jest-dom/extend-expect'
import { setup } from '@resultadosdigitais/front-hub/react/jest'
import 'jest-styled-components'
import fronthubConfig from '../front-hub.config'

setup(fronthubConfig)

Application not created with Create React App

If you didn't create your application with Create React App you'll need to create a configure jest.config.js file by using the Jest configuration.

jest.config.js
const { setup } = require('@resultadosdigitais/front-hub/react/jest')

setup(require('../front-hub.config.js'))

Wrapping your components with your custom render (React Testing Library)

Some times you'll need to include some things provided by the FrontHub in the render method like global context, providers, stores, etc. As React Testing Library advice, you can create your custom render method by re-exporting everything from React Testing Library. This way you can use your custom RTL from all your imports.

See the below example:

custom-testing-library.js
import {
renderWithTranslation as customRenderWithTranslation,
useMock,
withMock,
} from '@resultadosdigitais/front-hub/react/jest'
import { render as customRender } from '@testing-library/react'

export * from '@testing-library/react'

export const render = (comp, config) => {
// eslint-disable-next-line react-hooks/rules-of-hooks
return customRender(useMock(comp, config))
}

export const renderWithTranslation = async (comp, config, translation) => {
// eslint-disable-next-line react-hooks/rules-of-hooks
return customRenderWithTranslation(useMock(comp, config), translation)
}

withMock and instanceMock

Sometimes when you use some advanced feature provided by FrontHub such as useFeature, renderWithTranslation, withHostContext, or any other, you'll need to mock such features in an easy and quick way in your tests. That´s where withMock and instanceMock come into the picture.

instanceMock

You can use instanceMock when you need to mock some feature in a specific spec, that is, you don't need to reuse your mock in other specs.

Example:

Posts component
import React from 'react';
import { useTranslation } from 'react-i18next';

export default const Posts = ({ posts }) => {
const { t } = useTranslation();

return (
<Posts>
<h1>{t('postsTitle')}</h1>
{
posts.length > 0 && (
<ul>
{
posts.map(post => <li key={post.id}>{post.title}</li>)
}
</ul>
)
}
</Posts>
)
}
testing Posts component with instanceMock
import React from 'react'
import { render } from '@testing-library/react'
import {
instanceMock,
renderWithTranslation,
} from '@resultadosdigitais/front-hub/react/jest'
import Posts from '.'

const mockPosts = [
{ id: 1, title: 'Post title one' },
{ id: 2, title: 'Post title two' },
]

describe('Posts', () => {
it('should render a post with title "post title one"', () => {
const { getByText } = render(
renderWithTranslation(instanceMock(<Posts posts={mockPosts} />)),
)

expect(getByText(/post title one/i)).toBeInTheDocument()
})
})

withMock

You can use withMock when you need to reuse your mock in more than one spec, you need a reusable mock.

testing Posts component with withMock
import React from 'react'
import { render } from '@testing-library/react'
import {
withMock,
renderWithTranslation,
} from '@resultadosdigitais/front-hub/react/jest'
import Posts from '.'

const mockPosts = [
{ id: 1, title: 'Post title one' },
{ id: 2, title: 'Post title two' },
]

const frontHubPosts = withMock(Posts)

describe('Posts', () => {
it('should render a post with title "post title one"', () => {
const { getByText } = render(
renderWithTranslation(<fronHubPosts posts={mockPosts} />),
)

expect(getByText(/post title one/i)).toBeInTheDocument()
})

it('should render a post with title "post title two"', () => {
const { getByText } = render(
renderWithTranslation(<fronHubPosts posts={mockPosts} />),
)

expect(getByText(/post title two/i)).toBeInTheDocument()
})
})

renderWithFrontHub

You can use renderWithFrontHub to render a component wrapped by the basic FrontHub context.

info

The renderWithFrontHub function doesn't make localization and communication features available to the rendered component. Use renderWithTranslation and renderWithCommunication when you need to test these features.

Logo component
import logo from './logo.png'
import { Image } from '@resultadosdigitais/front-hub/react'

const Logo = () => {
return <Image alt="My company logo" src={logo} />
}

export default Logo
testing Logo component with renderWithFrontHub
import React from 'react'
import { renderWithFrontHub } from '@resultadosdigitais/front-hub/react/jest'
import Logo from './Logo'

describe('Logo', () => {
it('should render a image with alt text "My company logo"', () => {
const { getByRole } = renderWithFrontHub(<Logo />)
const logo = getByRole('img')

expect(logo).toHaveAttribute('alt', 'My company logo')
})
})