Testando Logs em Aplicações Laravel com Log::shouldReceive()

Posted on: September 05, 2025 10:08 AM

Posted by: Renato

Categories: Laravel log tests

Views: 213

Testando Logs em Aplicações Laravel com Log::shouldReceive() e Mockery

Testando Logs em Aplicações Laravel com Log::shouldReceive() e Mockery

Quando trabalhamos com testes unitários em aplicações Laravel, muitas vezes precisamos validar não apenas o retorno de métodos, mas também se determinadas ações ocorreram internamente. Um caso comum é verificar se mensagens de log foram geradas corretamente.

Por padrão, o Laravel utiliza o Monolog como biblioteca de logging, acessível através da facade Log. Em testes, no entanto, não é interessante que mensagens sejam gravadas em arquivos, enviadas para serviços externos ou até mesmo exibidas no console. Para evitar esses efeitos colaterais, podemos usar o poder do Mockery em conjunto com o método Log::shouldReceive().


O que é o Log::shouldReceive()?

O método shouldReceive() é utilizado para mockar (simular) a facade Log. Isso significa que, durante a execução dos testes, podemos substituir o comportamento real do log por uma versão controlada, permitindo:

  • Definir expectativas sobre quais métodos do log serão chamados.

  • Controlar quantas vezes esses métodos devem ser invocados.

  • Especificar quais parâmetros devem ser recebidos.

  • Evitar gravações reais em arquivos ou chamadas a serviços externos.

Em resumo, Log::shouldReceive() nos dá controle total sobre a interação com o sistema de logs em ambiente de teste.


Como funciona o Mockery nesse contexto?

O Mockery é a biblioteca utilizada pelo Laravel para criação de mocks e stubs. Com ele, conseguimos definir expectativas precisas de chamadas a métodos.

Ao usar Log::shouldReceive(), estamos na verdade configurando o comportamento esperado da facade Log por meio do Mockery.


Definindo Expectativas com shouldReceive()

A seguir, algumas formas comuns de definir expectativas sobre o uso do log:

1. Definindo o método esperado

Log::shouldReceive('error');

Aqui dizemos que esperamos que o método error() seja chamado.


2. Definindo a quantidade de chamadas

Log::shouldReceive('info')->once();
Log::shouldReceive('warning')->times(2);
Log::shouldReceive('debug')->zeroOrMoreTimes();
  • once() → deve ser chamado exatamente uma vez.

  • times(2) → deve ser chamado exatamente duas vezes.

  • zeroOrMoreTimes() → pode ser chamado qualquer número de vezes (inclusive nenhuma).


3. Validando argumentos

Log::shouldReceive('error')
    ->once()
    ->with('Erro crítico detectado', ['user_id' => 123]);

Aqui estamos dizendo que:

  • O método error() deve ser chamado uma vez.

  • Ele deve receber exatamente a mensagem "Erro crítico detectado" e o contexto ['user_id' => 123].

Se o método for chamado com outros argumentos, o teste falhará.


4. Definindo retorno (caso necessário)

Normalmente, métodos de log retornam void, mas ainda é possível simular retornos se o código depender disso:

Log::shouldReceive('info')
    ->andReturn(true);

Exemplo Prático

Suponha que temos um serviço que executa uma operação e, em caso de falha, registra um erro no log:

class MyService
{
    public function doSomethingWithError()
    {
        // Lógica qualquer...
        Log::error('An error occurred', ['context' => 'value']);
    }
}

Agora, queremos garantir que essa mensagem de erro seja registrada quando o método for chamado. Nosso teste ficaria assim:

use Illuminate\Support\Facades\Log;

class MyTest extends TestCase
{
    public function testSomethingLogsAnError()
    {
        Log::shouldReceive('error')
            ->once()
            ->with('An error occurred', ['context' => 'value']);

        $this->myService->doSomethingWithError();
    }
}

Se a mensagem de log não for disparada corretamente, o teste falhará.


Benefícios de usar Log::shouldReceive()

  1. Testes sem efeitos colaterais
    Evita gravação de arquivos ou chamadas externas durante a execução dos testes.

  2. Assertividade
    Garante que mensagens de log sejam emitidas corretamente, no formato e quantidade esperados.

  3. Isolamento
    Permite testar apenas a lógica de geração de logs, sem depender da implementação do Monolog ou da configuração de logging da aplicação.

  4. Integração com Mockery
    Oferece flexibilidade para criar mocks complexos e cenários de teste realistas.


Boas Práticas

  • Use Log::shouldReceive() apenas em testes unitários, não em testes de integração.

  • Sempre especifique a quantidade de chamadas (once(), times(n)) para evitar falsos positivos.

  • Valide os argumentos esperados com with() ou withArgs() para garantir que a mensagem de log está correta.

  • Mantenha os testes focados: não valide logs irrelevantes para o caso de teste.


Conclusão

O uso de Log::shouldReceive() em testes unitários no Laravel é uma forma poderosa de garantir que sua aplicação está registrando logs da maneira correta, sem efeitos colaterais e com assertividade. Ele faz parte do arsenal de boas práticas para escrever testes robustos, aproveitando a flexibilidade da biblioteca Mockery.

Se a sua aplicação depende fortemente de logs para auditoria, monitoramento ou depuração, testar o comportamento dos logs é tão importante quanto testar retornos de métodos.

 


1

Share

Donate to Site


About Author

Renato

Developer

Add a Comment

Blog Search


Categories

Laravel (227) PHP (151) linux (124) Variados (110) Dicas (58) ubuntu (58) developer (48) postgresql (45) database (44) sql (42) Docker (32) front-end (31) mysql (31) devops (26) webdev (24) programming (23) aws (19) tecnologia (19) eloquent (19) dba (18) OUTROS (17) backend (16) laravelphp (16) debian (12) dev (12) reactjs (10) 100DaysOfCode (10) git (10) react (10) nginx (9) inteligencia-artificial (9) PHP Swoole (9) node (9) javascript (9) linux-tools (8) Architecture (8) vue (7) github (7) ciencia (7) nodejs (6) api (6) vscode (6) webservice (6) jwt (6) vim (6) windows (6) arquitetura (6) authentication (5) ia (5) reactnative (5) rest (5) DevSecOps (5) servers (5) apache (5) macox (5) s3 (5) Kubernetes (4) gitlab (4) opensource (4) mariadb (4) jenkins (4) shell (4) mongodb (4) angular (4) autenticacao (4) wsl (4) Swoole (4) lets-encrypt (4) query (4) Raspberry (4) angularjs (4) inteligenciadedados (4) Padrao de design (4) artigo (4) google (4) npm (4) openai (4) js (3) mysqli (3) Black Hat (3) RabbitMQ (3) educacao (3) intel (3) CMS (2) sail (3) script (3) performance (3) json (3) authorization (3) phpswoole (3) ddd (3) blade (3) terminal (3) log (3) mac (3) fedora (3) containers (3) ssh (3) bash (3) hardware (3) tests (3) macos (3) web (2) jobs (3) websocket (3) db (3) politica (3) Curisidades (2) Solid (2) zsh (2) Go (2) BigLinux (2) POO (2) LazyVim (2) gource (2) Python (2) Oauth2 (2) android (2) unix (2) magento (2) iot (2) ffmpeg (2) combustivel (2) webhook (2) microservices (2) bancodedados (2) tailwind (2) homeOffice (2) html (2) openswoole (2) artificialintelligence (2) security (2) auth (2) cron (2) phpunit (2) kube (2) multiple_authen (2) policia (2) neovim (2) golang (2) noticias (2) livros (2) Transcribe (2) ElonMusk (2) redis (2) claude (2) ArchLinux (2) java (2) saude (1) seguranca (2) phpfpm (2) autorizacao (2) monitoring (2) laptop (2) gnome (2) powerbi (2) telefonia (2) nvm (2) imagick (2) maps (2) colors (2) Passport (2) JQuery (2) front (1) wine (1) covid19 (0) services (1) phpjasper (1) models (1) kali-linux (1) geojson (1) yarn (1) picpay (1) Monolith (1) banco (1) PNPM (1) Desenvolvedor (1) Structurizr (1) symfony (1) presenter (1) lider (1) guard (1) tensorflow (1) bootstrap (1) nuance (1) historia (1) dropbox (1) traefik (1) bug (1) akitando (1) llm (1) htm (1) transformers (1) cavalotroia (1) odd (1) m1 (1) Error (1) cinnamon (1) repmgr (1) federal (1) ruby (1) AppSec (1) orm (1) ArquiteturaDeSoftware (1) Passwordless (1) memcached (1) flow (1) compression (1) athena (1) Migration (1) workflow (1) cqrs (1) kitematic (1) geospacial (1) yeshua (1) data (1) sonarqube (1) Axios (1) pipelines (1) Mozilla (1) kvm (1) GitOps (1) sqlite (1) podcast (1) n8n (1) LaravelFilament (1) God (1) DesenvolvimentoProfissional (1) sw (1) bigtech (1) postgres (1) NoCookies (1) LeetCode (1) governancadedados (1) prf (1) nosql (1) Lideranca (1) Hackers (1) Bots (1) pytorch (1) nuxt (1) liquid (1) ec2 (1) transaction (1) c4 (1) rancher (1) algoritimo (1) Observability (1) Elasticsearch (1) translate (1) certbot (1) Oh My Zsh (1) ibm (1) escopos (1) usb (1) ckeditor (1) API_KEY_GOOGLE_MAPS (1) Manjaro (1) vicuna (1) coding (1) rust (1) markdown (1) JasperReports (1) Fibonacci (1) community (1) Samurai (1) payment (1) messaging (1) Jesus (1) flutter (1) militar (1) fullsta (1) smartphones (1) automacao (1) Monitor (1) zend (1) spaceship (1) PKCE (1) l2tp (1) Glacier (1) laraveloctane (1) Deus (1) binaural (1) gpt (1) bolsonaro (1) privacidade (1) linkedin (1) documentation (1) brain (1) adb (1) nvidia (1) host (1) ecommerce (1) c4-models (1) altadisponibilidade (1) octane (1) lucena (1) http (1) TypeScript (1) chatgpt (1) idiomas (1) eventdrive (1) uuid (1) restfull (1) aplicativo (1) optimization (1) mapas (1) Fetch (1) collections (1) RustLang (1) matematica (1) Filament (1) compactar (1) paypal (1) microg (1) forcas armadas (1) cor (1) auth (1) modelagemdedados (1) k8s (1) gasolina (1) wsl2 (1) csv (1) soap (1) piada (1) KubeCon (1) zorin-os (1) spring-boot (1) backup (1) playwright (1) Deepin (1) storage (1) benchmark (1) networking (1) Swoole (1) biologia (1) node-red (1) LETSENCRYPT (1) Grunt (1) Diagramas (1) boot (1) haru (1) dracula (1) TrabalhoEmEquipe (1) Brasil (1) queue (1) agi (1) llama (1) hotfix (1) economia (1) transcription (1) cache (1) Amazon (1) October (1) lumen (1) Hyperf (1) replication (1) faceapp (1) vala (1) cloudstack (1) rpi (1) apple (1) oracle (1) iode (1) ffaa (1) vpn (1) MeioAmbiente (1) firefox (1) composer (1) scheduling (1) Asahi (1) pendrive (1) microservice (1) front (1) OOD (0) controllers (0)

New Articles



Get Latest Updates by Email