Как издеваться над наблюдаемым значением из сервиса Angular 7? - PullRequest
1 голос
/ 03 мая 2019

Я пытался написать модульные тесты для моего компонента Angular. В настоящее время в моем сервисном вызове, чтобы получить данные для моего компонента, у меня есть наблюдаемая, которая получает значение true после завершения вызова. Это доступно для подписки в моем компоненте, чтобы компонент знал, когда был завершен вызов. Мне удалось смоделировать вызов данных в моем компоненте, но я изо всех сил пытаюсь найти способ смоделировать единственное наблюдаемое значение.

Все вопросы о SO, которые я могу найти, касаются насмешек над вызовом функции из службы в компоненте, но ни один из вопросов, которые я могу найти, не касается насмешки над одной наблюдаемой.

Вот мой вызов функции в сервисе. Как видите, наблюдаемой задается новое значение после запуска функции finalize:

  public getSmallInfoPanel(key: string): BehaviorSubject<InfoPanelResponse> {

    if (key) {
      this.infoPanel = new BehaviorSubject<InfoPanelResponse>(null);

      this.http.get(`${this.apiUrl}api/Panels/GetInfoPanel/${key}`).pipe(
          retry(3),
          finalize(() => {
            this.hasLoadedSubject.next(true);
          }))
        .subscribe((x: InfoPanelResponse) => this.infoPanel.next(x));
    }
    return this.infoPanel;
  }

Вот как я создал Observable в сервисе:

 private hasLoadedSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
 public hasLoadedObs: Observable<boolean> = this.hasLoadedSubject.asObservable();

Затем в моем компоненте я подписываюсь на Observable, созданный из BehaviourSubject:

public hasLoaded: boolean;

  ngOnInit() {

    this.infoPanelSmallService.hasLoadedObs.subscribe(z => this.hasLoaded = z);

  }

Когда я запускаю ng test, компонентный тест не пройден, потому что он не знает, что такое hasLoadedObs, поэтому он не может подписаться на него.

Дайте мне знать, могу ли я предоставить больше информации. Спасибо.

ОБНОВЛЕНИЕ 1

describe('InformationPanelSmallComponent', () => {
  let component: InformationPanelSmallComponent;
  let fixture: ComponentFixture<InformationPanelSmallComponent>;

  let mockInfoPanelService;
  let mockInfoPanel: InfoPanel;
  let mockInfoPanelResponse: InfoPanelResponse;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule,
        FontAwesomeModule,
        HttpClientTestingModule
      ],
      declarations: [InformationPanelSmallComponent, CmsInfoDirective],
      providers: [
        { provide: InfoPanelSmallService, useValue: mockInfoPanelService }
      ]
    })
    .compileComponents();
  }));

  beforeEach(() => {

    mockInfoPanel = {
      Title: 'some title',
      Heading: 'some heading',
      Description: 'some description',
      ButtonText: 'some button text',
      ButtonUrl: 'some button url',
      ImageUrl: 'some image url',
      Key: 'test-key',
      SearchUrl: '',
      VideoUrl: ''
    }

    mockInfoPanelResponse = {
      InfoPanel: mockInfoPanel
    }

    fixture = TestBed.createComponent(InformationPanelSmallComponent);
    component = fixture.componentInstance;

    mockInfoPanelService = jasmine.createSpyObj(['getSmallInfoPanel']);

    component = new InformationPanelSmallComponent(mockInfoPanelService);

    component.key = "test-key"

  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
  //TO DO
  it('should get info panel from info panel service', () => {
    mockInfoPanelService.getSmallInfoPanel.and.returnValue(of(mockInfoPanelResponse));
    component.ngOnInit();

    expect(mockInfoPanelService.getSmallInfoPanel).toHaveBeenCalled();
    expect(component.infoPanel).toEqual(mockInfoPanel);
  });
});


1 Ответ

1 голос
/ 28 мая 2019

Я обнаружил, что это связано с тем, что я издевался над сервисом и создавал компонент. Я также использовал TestBed.overrideProvider, что отличается от того, что я использовал выше. Это конечный файл теста:


describe('InformationPanelSmallComponent', () => {
  let component: InformationPanelSmallComponent;
  let fixture: ComponentFixture<InformationPanelSmallComponent>;

  let mockInfoPanelService;
  let mockInfoPanel: InfoPanel;
  let mockInfoPanelResponse: InfoPanelResponse;

  beforeEach(async(() => {
    mockInfoPanelService = jasmine.createSpyObj(['getSmallInfoPanel', 'hasLoadedObs']);

    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule,
        FontAwesomeModule,
        HttpClientTestingModule
      ],
      declarations: [InformationPanelSmallComponent, CmsInfoDirective, UrlRedirectDirective],
      providers: [
        { provide: 'BASE_URL', useValue: '/' },
        { provide: 'API_URL', useValue: '/' }
      ]
    })

    TestBed.overrideProvider(InfoPanelSmallService, { useValue: mockInfoPanelService });

    TestBed.compileComponents();
  }));

  beforeEach(() => {

    mockInfoPanel = {
      Title: 'some title',
      Heading: 'some heading',
      Description: 'some description',
      ButtonText: 'some button text',
      ButtonUrl: 'some button url',
      ImageUrl: 'some image url',
      Key: 'test-key',
      SearchUrl: '',
      VideoUrl: ''
    }

    mockInfoPanelResponse = {
      InfoPanel: mockInfoPanel
    }

    fixture = TestBed.createComponent(InformationPanelSmallComponent);
    component = fixture.componentInstance;

    mockInfoPanelService.getSmallInfoPanel.and.returnValue(of(mockInfoPanelResponse));
    mockInfoPanelService.hasLoadedObs = of(true);

    component.key = "test-key"

    fixture.detectChanges();

  });

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

  describe('ngOnInit', () => {
    it('should get info panel from info panel service', () => {
      expect(component.hasLoaded).toEqual(true);
      expect(mockInfoPanelService.getSmallInfoPanel).toHaveBeenCalled();
      expect(component.infoPanel).toEqual(mockInfoPanel);
    });

    it('should get loaded is true from service', () => {
      expect(component.hasLoaded).toEqual(true);
    });
  });
});

У меня больше не было ошибок, и тесты действительно работали правильно. Спасибо @RuiMarques и другим за вклад.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...