Testando Componentes React com MobX Stores: Um Guia Prático com Exemplos
Tags: react, mobx, typescript, programming
Published: 2024-02-19 20:09:11

## Introdução

No desenvolvimento de aplicações modernas com React e MobX, a implementação de testes sólidos é crucial para garantir a confiabilidade e a manutenibilidade do código. Este artigo explora as práticas recomendadas e fornece exemplos práticos de como testar componentes que acessam stores do MobX.

## Configurando o Ambiente de Teste

Antes de começarmos, é importante configurar o ambiente de teste. Vamos usar Jest como nosso framework de testes e `@testing-library/react` para renderizar os componentes.

```bash
npm install --save-dev jest @testing-library/react mobx-react-lite
```

## Estruturas dos Testes

### 1. Isolamento de Stores

A primeira etapa é isolar a store do MobX para garantir que os testes não sejam afetados por estados anteriores.

```typescript
import { MyStore } from './MyStore';

let store: MyStore;

beforeEach(() => {
  store = new MyStore();
});
```

### 2. Mocking de Stores e Actions

Para testar componentes que interagem com a store, podemos mockar as stores e suas actions.

```typescript
jest.mock('./MyStore', () => ({
  MyStore: jest.fn().mockImplementation(() => ({
    fetchData: jest.fn(),
    data: [],
  })),
}));
```

### 3. Provendo Stores com React Context

Utilize o `Provider` do `mobx-react-lite` para envolver seus componentes nos testes.

```typescript
import { Provider } from 'mobx-react-lite';

test('renders with provided store', () => {
  render(
    <Provider myStore={store}>
      <MyComponent />
    </Provider>
  );
});
```

## Exemplos de Testes

### Testando a Renderização de Componentes

Verifique se o componente renderiza corretamente com os dados da store.

```typescript
test('renders data from the store', () => {
  store.data = ['Item 1', 'Item 2'];
  const { getByText } = render(
    <Provider myStore={store}>
      <MyListComponent />
    </Provider>
  );

  expect(getByText('Item 1')).toBeInTheDocument();
  expect(getByText('Item 2')).toBeInTheDocument();
});
```

### Testando Interações do Usuário

Simule interações do usuário e verifique se as ações da store são chamadas.

```typescript
test('calls store action on button click', () => {
  const fetchDataMock = jest.fn();
  store.fetchData = fetchDataMock;
  
  const { getByText } = render(
    <Provider myStore={store}>
      <MyComponent />
    </Provider>
  );

  fireEvent.click(getByText('Load Data'));
  expect(fetchDataMock).toHaveBeenCalled();
});
```

### Testando Reações a Mudanças de State

Teste a reatividade dos componentes a mudanças no state da store.

```tsx
test('updates component when store changes', () => {
  const { getByText, rerender } = render(
    <Provider myStore={store}>
      <MyComponent />
    </Provider>
  );

  store.addItem('New Item');
  rerender(
    <Provider myStore={store}>
     <MyComponent />
    </Provider>
  );
  expect(getByText('New Item')).toBeInTheDocument();
});
```

### Testando a Lógica de Estado Local Complementar

Alguns componentes podem ter estado local além da store. Teste também essa lógica.

```tsx
test('handles local state changes', () => {
  const { getByLabelText, getByText } = render(
    <Provider myStore={store}>
      <MyFormComponent />
    </Provider>
  );

  fireEvent.change(getByLabelText('Item Name'), { target: { value: 'New Local Item' } });
  fireEvent.submit(getByText('Submit'));

  expect(store.data.includes('New Local Item')).toBe(true);
});

```

## Testes End-to-End

Além de testes unitários e de integração, considere testes end-to-end para simular a experiência do usuário. Ferramentas como Cypress ou Puppeteer podem ser utilizadas para este fim.

## Conclusão

Testar componentes com MobX requer uma abordagem cuidadosa para mockar stores e garantir que a integração entre reatividade e UI esteja correta. Com mocks apropriados e testes de integração bem estruturados, você pode construir uma suite de testes confiável para suas aplicações React + MobX.