Teste de Unidade em Angular 15 Sem TestBed

Apr 12 2023
Preenchendo a lacuna entre o DI baseado em construtor e o teste de DI baseado em injeção sem o TestBed Angular 14 introduziu a capacidade de usar a função de injeção em classes como componentes, diretivas e pipes. Os autores de bibliotecas adotaram esse recurso e muitos abandonaram a injeção de dependência baseada em construtor ('DI').

Fazendo a ponte entre DI baseada em construtor e testes de DI baseados em injeção sem TestBed

Angular 14 introduziu a capacidade de usar a função de injeção em classes como componentes, diretivas e pipes. Os autores de bibliotecas adotaram esse recurso e muitos abandonaram a injeção de dependência baseada em construtor ('DI'). Também inspirou funções reutilizáveis ​​chamadas DI Functions .

Existem muitas abordagens usando o TestBed que permitem testar e até simular dependências fornecidas pela função Inject.

No entanto, e se você não quiser usar o TestBed? Talvez por questões de desempenho , talvez você prefira isolar os testes de unidade do DOM por padrão, ou talvez tenha notado que o Angular está introduzindo utilitários para facilitar a execução de funções em um contexto de injeção com provedores.

tl;dr:

  • execute npm i @ngx-unit-test/inject-mocks -Dpara instalar funções utilitárias para testar a unidade de qualquer classe ou função Angular sem TestBed.

Este artigo (1) resume um componente que precisa de teste de unidade, (2) demonstra como testar esse componente em Angular 15+ sem TestBed e (3) mostra como testar uma função DI sem TestBed.

1. A configuração: um componente que precisa de teste de unidade

Aqui está um HomeComponent simples escrito em Angular 15 que usa a função de injeção:

O componente injeta um WidgetsFacade, acessa alguns observáveis ​​expostos por essa fachada e aciona um método de fachada durante o ngOnInit.

2. Fornecendo Dependências Simuladas

Então, como você poderia zombar do WidgetsFacade injetado sem usar o TestBed?

Se você apenas executar a especificação sem o TestBed, receberá este erro:

Erro NG0203 lançado ao testar um componente sem fornecer dependências

Para fornecer o serviço e simular suas funções, existem duas etapas:

Primeiro, crie um método utilitário que envolva o @angular/coreInjetor:

Este utilitário aproveita a classe interna do Angular Injectorpara fornecer automaticamente dependências para uma determinada classe. Você pode notar que o nome é classWithProviderse não componentWithProviders. Isso ocorre porque o utilitário funciona com Componentes, Serviços, Diretivas e Pipes!

Em segundo lugar, use classWithProvidersem um arquivo de especificação:

Vamos percorrer cada etapa no arquivo de especificação:

  1. Declare uma variável facadeMock digitada como Partial<WidgetsFacade>. Use Partial para obter inferência de tipo na próxima etapa.
  2. Atribuir objeto simulado : crie um objeto JavaScript e atribua jest.fn()ao método que você precisa simular.
  3. Obter componente com contexto de injeção : graças ao classWithProvidersutil, o componente retornado tem o provedor simulado!
  4. FacadeMock é fornecido para HomeComponent como o WidgetsFacade

Uma limitação do classWithProvidersé que ele não funciona com Funções de Injeção de Dependência (Funções DI). A solução atual para testar DI Functions envolve TestBed.runInInjectionContext, que foi lançada no Angular 15.1.0 .

Com base no exemplo do TestBed, é possível criar um utilitário autônomo que forneça uma solução semelhante para testar funções DI com provedores simulados:

Na verdade, a equipe Angular já está trabalhando em um novo utilitário runInInjectionContext que substitui e estende o método runInContext.

Conclusão

Os utilitários classWithProviderse foram inspirados no código-fonterunFnInContext do Angular.io . Dei o passo extra de agrupar esses utilitários em um pacote npm . Obrigado a Josh Van Allen e Rafael Mestre por sua visão e ajuda no desenvolvimento desses utilitários.

Sobre o HeroDevs

HeroDevs é um estúdio de consultoria e engenharia de software especializado em desenvolvimento front-end. Nossa equipe é autora ou coautora de projetos como Angular CLI, Angular Universal, Scully, XLTS — suporte estendido de longo prazo para AngularJS, Vue2, Protractor e muitos outros. Trabalhamos com startups de rápido crescimento e algumas das maiores empresas do mundo, como Google, GE, Capital One, Experian, T-Mobile, Corteva e outras. Saiba mais sobre nós em herodevs.com .