DEV Community

Denis Augusto
Denis Augusto

Posted on

Você testou a API funcionando. E quando ela cair?

O caminho feliz sempre passa. O problema é o outro.

Sua integração com o gateway funciona. Você testou. O teste tá verde. Deploy feito, tá em produção há meses.

Aí, numa terça qualquer, o gateway devolve um erro 500. Instabilidade do lado deles.

E o seu app? Cospe uma tela branca com Undefined array key "transaction_id" na cara do cliente. Porque seu código pegou a resposta de erro e tentou ler o transaction_id que não existe ali.

Você testou a API funcionando. Nunca testou ela falhando. E é exatamente aí que mora o bug.

O teste que só conhece o dia bonito

Olha o teste típico de integração. Aposto que o seu se parece com esse:

public function test_processa_o_pagamento(): void
{
    Http::fake([
        'gateway.com/*' => Http::response([
            'status'         => 'aprovado',
            'transaction_id' => 'tx_123',
        ], 200),
    ]);

    $resultado = $this->service->cobrar($pedido);

    $this->assertTrue($resultado->aprovado);
}
Enter fullscreen mode Exit fullscreen mode

Bonito. Verde. E completamente ingênuo.

Ele responde uma única pergunta: "quando dá tudo certo, meu código funciona?". Ótimo. Mas a produção não é só o dia bonito. A API vai devolver 500, vai dar timeout, vai responder um JSON estranho, vai ficar fora do ar. E você nunca escreveu uma linha testando o que acontece nesses casos.

O caminho feliz é o que menos quebra. O caminho de falha é onde o cliente vê tela branca.

O resgate: Http::fake() também simula desastre

Aqui tá a beleza de mockar a API — você não fica refém de esperar ela cair pra ver o que acontece. Você manda ela cair. Na hora que quiser, no teste que quiser.

public function test_gateway_fora_do_ar_nao_quebra_o_app(): void
{
    // simula o gateway devolvendo erro 500
    Http::fake([
        'gateway.com/*' => Http::response('Service Unavailable', 500),
    ]);

    $resultado = $this->service->cobrar($pedido);

    // seu código degrada com elegância, em vez de explodir?
    $this->assertFalse($resultado->aprovado);
    $this->assertEquals('gateway_indisponivel', $resultado->motivo);
    $this->assertEquals('pendente', $pedido->fresh()->status);
}
Enter fullscreen mode Exit fullscreen mode

Esse teste vale ouro. Ele te obriga a responder: "quando o gateway cai, meu pedido fica num estado consistente ou vira lixo?". Se o teste passa, você sabe que o cliente vê uma mensagem decente e o pedido fica pendente pra retentar — não uma tela branca.

Os três desastres que você precisa testar

Não é só o erro 500. O mundo real tem sabores variados de falha:

// 1. Erro do servidor (a API respondeu, mas com pau)
Http::fake(['gateway.com/*' => Http::response('', 500)]);

// 2. Resposta inesperada (mudaram o contrato, ou veio corrompido)
Http::fake(['gateway.com/*' => Http::response(['algo' => 'diferente'], 200)]);

// 3. A API nem respondeu (timeout / fora do ar)
Http::fake(fn () => throw new ConnectionException('timeout'));
Enter fullscreen mode Exit fullscreen mode

Cada um exercita um pedaço diferente do seu tratamento de erro. O 500 testa seu throw(). A resposta estranha testa se você valida o que recebeu antes de usar. A ConnectionException testa o que acontece quando a requisição nem chega — o cenário do post sobre timeout e retry, agora coberto por teste.

A pegadinha: caminho de falha sem tratamento não "passa", ele engana

Cuidado com uma armadilha sutil. Se seu código não trata o erro, esse teste de falha pode passar por engano — porque o Laravel lança a exceção e o teste morre com ela, ou o assert bate em cima de um estado que você nem pensou.

O teste de falha só tem valor se você escreveu o teste esperando um comportamento específico e digno: uma flag aprovado = false, um status pendente, uma exceção sua tratada. Se você não sabe o que seu código deveria fazer quando a API cai... esse é o verdadeiro bug, e o teste acabou de te mostrar.

Antes de você fechar a aba

O caminho feliz é o mínimo. Ele prova que seu código funciona no melhor dos mundos — que é justamente o mundo que menos acontece.

O teste que te salva de plantão às 2 da manhã é o do caminho de falha. Pega a sua integração externa mais crítica e se pergunta: "eu tenho um teste que simula essa API caindo?". Se a resposta é não, você já sabe qual teste escrever amanhã.

Me conta: você testa o caminho de falha das suas integrações, ou só o dia bonito? Sem julgamento — a maioria só testa o feliz. 👀

Top comments (0)