Имитация автономной директивы в автономном компоненте

Я пытаюсь написать модульный тест для автономного компонента и издеваться над его зависимостью. Этот автономный компонент имеет следующее содержимое:

      import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { DemoDirectiveDirective } from './demo-directive.directive';

@Component({
  selector: 'app-demo-cmp',
  standalone: true,
  imports: [CommonModule,DemoDirectiveDirective],
  templateUrl: './demo-cmp.component.html',
})
export class DemoCmpComponent implements OnInit {
  constructor() {}

  ngOnInit(): void {}
}

и DemoDirectiveDirective имеет следующее содержание:

      import { Directive, ElementRef } from '@angular/core';

@Directive({
  selector: '[appDemoDirective]',
  standalone: true,
})
export class DemoDirectiveDirective {
  constructor(private hostElement: ElementRef) {
    this.hostElement.nativeElement.innerHTML += 'Update from directive! ';
  }
}

я хочу проверитьDemoCmpComponentтак:

      import { ComponentFixture, TestBed } from '@angular/core/testing';

import { DemoCmpComponent } from './demo-cmp.component';

describe('DemoCmpComponent', () => {

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [DemoCmpComponent],
    }).compileComponents();
  });

  it('should create', () => {
    const fixture = TestBed.createComponent(DemoCmpComponent);
    fixture.detectChanges();

    expect(fixture.nativeElement.querySelector('p').innerHTML).toBe(
      'demo-cmp works!'
    );
  });
});

Этот тест не пройден, так как содержимоеpтег будетUpdate from directive! demo-cmp works!.

Чего мне здесь не хватает, так это шага, на котором я издеваюсьDemoDirectiveDirectiveчто я не знаю, как это сделать, и я не нахожу никаких ресурсов для этого на странице Angular.

Обратите внимание, что это всего лишь демонстрационный тест, доказательство концепции. Пожалуйста, игнорируйте названия компонентов и лишний тест.

Вот репозиторий GitHub с кодом.

1 ответ

Один из самых простых способов издеваться над объявлением angular — использовать библиотеку для имитации, например.

ng-mocksподдерживает автономный компонент, и егоMockBuilderзнает, как имитировать импорт автономных объявлений.

В вашем случае тест может быть таким:

      import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MockBuilder } from "ng-mocks";

import { DemoCmpComponent } from './demo-cmp.component';

describe('DemoCmpComponent', () => {

  beforeEach(() => {
    return MockBuilder(DemoCmpComponent);
    // it will mock DemoDirectiveDirective automatically,
    // because it's a dependency of DemoCmpComponent.
  });

  it('should create', () => {
    const fixture = TestBed.createComponent(DemoCmpComponent);
    fixture.detectChanges();

    expect(fixture.nativeElement.querySelector('p').innerHTML).toBe(
      'demo-cmp works!'
    );
  });
});

Вот живой пример: https://codesandbox.io/s/bold-kate-1gkymd?file=/src/test.spec.ts:770-812

Другие вопросы по тегам