Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Teste unitário do Viewchildren com ElementRef

Galera, bom dia. To com uma dúvida em um teste unitário que está sinistro, se puderem dar um help eu agradeço. Basicamente não to conseguindo testar um componente, seguem os códigos simplificados.

@Component({
  selector: 'app-offer-card',
  templateUrl: './offer-card.component.html',
  styleUrls: ['./offer-card.component.scss']
})
export class OfferCardComponent implements OnInit {
  @ViewChildren('container') containeres: QueryList<any>;

  constructor(
    public elementRef: ElementRef
  ) {}

  ngOnInit(): void {
  }

  clickAccordion(index: number) {
    let container = this.containeres.get(index).nativeElement;

    if (container.classList.contains('show')) {
      console.log('show')
    } else {
      console.log('NoShow')
    }
  }

Encurtei o código para ficar mais fácil de entender, o problema é que no evento clique eu disparo o método clickAccordion e nos testes unitários devido ao objeto containeres não estar conseguindo fazer o mock dele, rola uma mensagem de erro TypeError: Cannot read properties of undefined (reading 'nativeElement')

No teste está assim

it('Deve chamar funções de controle do accordion quando clicar no botão de Accordion', fakeAsync(() => {
    spyOn(component, 'toggleAccordion');
    component.toggleAccordion(0);
    expect(component.toggleAccordion).toHaveBeenCalled();
  }));
})

Se eu deixo assim, o teste OK, mas não resolve o coverage, se eu retiro a linha do spyOn, aí ele dá o erro acima, o que fazer nesse caso?

1 resposta
solução!

Oi Paulo, tudo bem?

Desculpe a demora em retornar.

Entendo que você está com dificuldades para testar o componente OfferCardComponent, especificamente no método clickAccordion que utiliza o ViewChildren e o ElementRef. Você menciona que o erro ocorre devido ao objeto containeres não estar conseguindo fazer o mock dele, gerando uma mensagem de erro ao tentar acessar a propriedade 'nativeElement'.

Uma solução para esse problema é fornecer uma lista de elementos simulados para o objeto QueryList de containeres, para que ele possa ser acessado no momento dos testes. Você pode fazer isso usando o método reset e o método push do QueryList.

Abaixo está um exemplo de como você pode testar o método clickAccordion:

it('Deve chamar funções de controle do accordion quando clicar no botão de Accordion', fakeAsync(() => {
    const mockContainer = {
      nativeElement: {
        classList: {
          contains: () => true
        }
      }
    };
    component.containeres.reset([mockContainer]);

    spyOn(component, 'toggleAccordion');
    component.clickAccordion(0);
    expect(component.toggleAccordion).toHaveBeenCalled();
  }));

Nesse exemplo, criei um objeto mockContainer com uma propriedade nativeElement que possui um método contains simulado, que sempre retorna true. Em seguida, resetei o objeto containeres com esse mockContainer usando o método reset. Depois, eu chamei o método clickAccordion passando o índice 0 e verifiquei se o método toggleAccordion foi chamado.

Dessa forma, você consegue simular o objeto containeres e garantir que seus testes cubram essa parte do código. Vale ressaltar que é importante pensar em outros cenários que possam ser testados para garantir a cobertura do seu código.

Espero que tenha te ajudado.

Um abraço e bons estudos.