DEV Community

Alan Pinhel
Alan Pinhel

Posted on

Como eu melhorei meus testes utilizando React Context

A Context é uma excelente forma de gerenciar estados em aplicações React e hoje em dia em muitos cenários dispensam o uso de bibliotecas adicionais para tal fim.

Uma das vantagens é a facilidade e simplicidade de testar os componentes que fazem uso de contextos com react-testing-library.

Veja como costumo fazer nos meus projetos:

export type User = {
  name: string;
};
Enter fullscreen mode Exit fullscreen mode
import { createContext } from 'react';
import { User } from './user';

export const UserContext = createContext<User>({} as User);
Enter fullscreen mode Exit fullscreen mode
import useSWR from 'swr';
import { User } from './user';
import { UserContext } from './user-context';

type Props = {
  children: React.ReactNode;
};

export function UserProvider({ children }: Props) {
  const { data, isLoading, error } = useSWR<User>('/api/user');

  if (error) {
    return <div>Erro ao carregar usuário</div>;
  }

  if (isLoading) {
    return <div>Carregando...</div>;
  }

  return (
    <UserContext.Provider value={data || ({} as User)}>
      {children}
    </UserContext.Provider>
  );
}
Enter fullscreen mode Exit fullscreen mode
import { useUser } from './useUser';

export function UserGreeter() {
  const user = useUser();

  if (user.name) {
    return <div>Olá, {user.name}!</div>;
  }

  return <div>Olá, visitante!</div>;
}
Enter fullscreen mode Exit fullscreen mode

Vamos garantir no teste que a regra de saudação seja respeitada corretamente:

import { render, screen } from '@testing-library/react';
import { UserGreeter } from './user-greeter';
import { UserProviderMock } from './user-provider-mock';

describe('UserGreeter', () => {
  it('should greet the user', () => {
    render(
      <UserProviderMock>
        <UserGreeter />
      </UserProviderMock>,
    );

    expect(screen.getByText('Olá, John Doe!')).toBeInTheDocument();
  });

  it('should greet the anonymous user', () => {
    render(
      <UserProviderMock value={{}}>
        <UserGreeter />
      </UserProviderMock>,
    );

    expect(screen.getByText('Olá, visitante!')).toBeInTheDocument();
  });
});
Enter fullscreen mode Exit fullscreen mode

Observe que criei o UserProviderMock com valores padrão, para evitar repetições em todos os testes dos componentes que dependem do User:

import { User } from './user';
import { UserContext } from './user-context';

type Props = {
  children: React.ReactNode;
  value?: Partial<User>;
};

export function UserProviderMock({ children, value }: Props) {
  return (
    <UserContext.Provider value={{ name: 'John Doe', ...value }}>
      {children}
    </UserContext.Provider>
  );
}
Enter fullscreen mode Exit fullscreen mode

Você ainda acha necessário o uso de bibliotecas de gerenciamento de estado? Por favor, deixe sua opinião nos comentários.

Top comments (0)