Как протестировать компонент с @Input и набрать Observable - PullRequest
0 голосов
/ 28 сентября 2018

Я немного новичок в написании модульных тестов для Angular и не могу понять, как написать модульные тесты для компонента с помощью директивы @Input.

Вот мой

== file.component.ts

import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'app-bugs-table',
  templateUrl: './bugs-table.component.html',
  styleUrls: ['./bugs-table.component.scss']
})
export class BugsTableComponent implements OnInit {
//   priorityData: any = [];
  @Input() bugsDataService;
  @Input() gridItemComponent;
  constructor(
  ) {  }

  ngOnInit() {

  }
    ngAfterViewInit() {
this.bugsDataService.subscribe(response => {
  this.bugsData = response;
})

}}

Вот мой file.component.spec.ts

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { FormsModule, ReactiveFormsModule, } from '@angular/forms';
import { HttpModule, BrowserXhr } from "@angular/http";

fdescribe('BugsTableComponent', () => {
  let component: BugsTableComponent;
  let fixture: ComponentFixture<BugsTableComponent>;
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ BugsTableComponent ],
      imports: []
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(BugsTableComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  fit('should create', () => {
    expect(component).toBeTruthy();
  });
});

Но происходит сбой с ошибкой:

× должен создать HeadlessChrome 69.0.3497 (Windows 10.0.0) TypeError: Невозможно прочитать свойство 'subscribe' из неопределенного

Я знаю, это потому, что bugsDataService (который можно наблюдать) не определено.Может ли кто-нибудь, пожалуйста, помогите исправить это.Пожалуйста, дайте мне знать, если вам нужна дополнительная информация.

Ответы [ 2 ]

0 голосов
/ 29 сентября 2018
beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ BugsTableComponent ],
      imports: [],
      providers: [BugsDataService] // inject service here 
    })
    .compileComponents();
  }));

Это должно исправить ошибку, но

Если вы хотите смоделировать реальное поведение службы, лучше было бы создать фиктивный сервис, расширяющий BugsDataService, и использовать его в случаях модульного тестирования, чтобыпредоставить ложные данные

пример

@Injectable()
export class BugsDataMockService extends BugsDataService {

overridenMethod() {
return Observable.of( { data : yourmockresponse });
}


And in your Spec file (Unit test)
beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ BugsTableComponent ],
      imports: [],
      providers: [ { provide: BugsDataService, useClass: BugsMockDataService } ] // Use Mock Service instead of original one 
    })
    .compileComponents();
  }));
0 голосов
/ 29 сентября 2018

следующие работы:

Включить этот импорт:

import { of } from 'rxjs';

Измените блок beforeEach для файла на:

beforeEach(() => {
  fixture = TestBed.createComponent(BugsTableComponent);
  component = fixture.componentInstance;

  // needed because ngAfterViewInit gets called and if there isn't an observable to subscribe to it will fail
  component.bugsDataService = of(null);

  fixture.detectChanges();
});

Напишите тест:

it('Should assign the input value to bugsdata', () => {
  // Arrange
  component.bugsData = {}; // to make sure it's empty at the start
  const resultFromService = {hello: 'world'};
  component.bugsDataService = of(resultFromService); // this creates an observable from resultFromService

  // Act
  component.ngAfterViewInit();

  // Assert
  expect(component.bugsData).toEqual(resultFromService);
});

Некоторые примечания:

  • Я заметил, что у вашего компонента есть ngAfterViewInit, но класс его не реализует.Если вы не используете ngOnInit, замените его в объявлении класса на ngAfterViewInit и обновите импорт.
  • Если вы не хотите вносить изменения, предложенные мной в блоке beforeEach, вы можете переместитьстрока подписки от ngAfterViewInit до отдельного метода, который вызывается ngAfterViewInit.Тем не менее, вам нужно будет шпионить за ним, чтобы он на самом деле не вызывался.
...