Ng-Mocks: pare de sofrer com dependências nos seus testes

Andrew Rosário
3 min readJun 19, 2023

O framework Angular oferece todo um setup para a escrita de testes automatizados. Por padrão utilizamos o Jasmine e o Karma como ferramentas para os testes, e ao gerar building blocks (componentes, services, pipes, diretivas, etc.) com o Angular CLI, automaticamente é gerado o arquivo de teste.

O intuito do Angular é oferecer uma maior agilidade para que o desenvolvedor não precise se preocupar com configurações iniciais. Porém na prática não é tão simples assim.

Imagine que você precise testar um componente que tem a dependência de um service e também possui componentes filhos. Dentro da configuração do seu teste será necessário informar essas dependências, caso contrário ele irá quebrar. Estes são dois exemplos de erro que serão exibidos caso você não configure corretamente o TestBed:

Error: src/app/app.component.html:1:1 - error NG8001: 'app-child' is not a known element:

If 'app-child' is an Angular component, then verify that it is part of this module.
If 'app-child' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.
Error: StaticInjectorError(DynamicTestModule)[ApiService -> HttpClient]: 
StaticInjectorError(Platform: core)[ApiService -> HttpClient]:
NullInjectorError: No provider for HttpClient!

Porém somente informar as dependências diretas pode não ser suficiente! O service injetado no componente pode ter outras dependências. Os componentes filhos podem ter outros componentes filhos também! No fim, o desenvolvedor passa mais tempo informando as dependências do que escrevendo os testes de fato.

Mocks com a biblioteca ng-mocks

O termo “Mock” é utilizado para descrever um caso especial de objetos que imitam objetos reais para teste. É exatamente esse o objetivo da biblioteca ng-mocks.

npm install ng-mocks --save-dev

Com ela podemos mockar componentes, services, diretivas, pipes e até módulos inteiros. É possível realizar mocks sem utilizar nenhuma biblioteca, mas a grande vantagem do ng-mocks é que conseguimos transformar as dependências em mocks mantendo as interfaces como estão, mas escondendo sua implementação.

Ela preza pela facilidade e a simplicidade ao mockar toda unidade de código com uma simples função. Isso facilita na hora de escrever testes e mantém a legibilidade do código.

Confira a documentação oficial da biblioteca para conhecer muitos outros recursos que ela oferece.

Utilize mocks com sabedoria

Uma vez que mockamos todas as dependências, estamos criando um teste unitário, ou seja, estamos testando se a menor parte do código está funcionando. Existem casos que essa prática é importante, mas existem outros casos onde um teste de integração possa gerar mais valor.

Vamos pegar como exemplo um smart component que depende de vários outros dumb components para entregar uma funcionalidade. Este componente reage a vários Outputs destes componentes filhos. Se no teste você mockar todos esses componentes então não será possível testar a funcionalidade como um todo.

É muito importante entender até onde um componente deve ir e quais são suas responsabilidades. O teste pode te guiar a escrever componentes mais desacoplados. Utilize mocks com o ng-mocks quando você possuir dependências que de fato não vão interferir no comportamento crucial do seu componente ou service.

Quer aprender a escrever testes mais eficientes no Angular? Então não deixe de conferir este meu artigo!

--

--

Andrew Rosário

Desenvolvedor Front-end, mentor e palestrante. Apaixonado por tecnologia e por compartilhar conhecimento.