簡體   English   中英

Angular 8 Jasmine 和業力測試:模擬的 ngonit promise 值未在 DOM 中呈現

[英]Angular 8 Jasmine and karma testing: mocked ngonit promise value is not rendered in the DOM

運行測試時,我在測試中的模擬數據不會顯示在標記中。 無論我嘗試什么(fakeasync、done、stubs),運行測試后 promise 的內容都不會呈現在標記中。

誰能告訴我為什么這個模擬的 promise 數據不會顯示在 dom 中。 我幾乎花了 2 天時間,無論我嘗試什么,它都無法正常工作。 我正在使用 angular 8 並開始認為這是框架中的錯誤。

我有以下標記:

<div>
    <div class="pt-8">
        <!-- Displays -->
        <ul>
            <li *ngFor="let worker of workers">{{worker.getName()}}</li>
        </ul>

        <!-- DOES NOT DISPLAY -->
        <ol>
            <li *ngFor="let centre of centres">{{centre.name}}</li>
        </ol>
    </div>
</div>

這是 class:

import { Component, OnInit, Input, Inject } from '@angular/core';
import { WorkcentersService } from 'app/services/workcenters.service';
import { Workcenter } from 'app/model/workcenter';
import { User } from 'app/model/user';

@Component({
  selector: 'test',
  templateUrl: './test.component.html',
  styleUrls: ['./test.component.scss']
})
export class TestComponent implements OnInit {
  workers: User[];
  centres: Workcenter[];

  constructor(private workcentersService: WorkcentersService) { }

  ngOnInit(): void {
    let user1 = new User(); user1.name = "worker 1"; user1.surname = "surname1";
    let user2 = new User(); user2.name = "worker 2"; user2.surname = "surname2";
    let user3 = new User(); user3.name = "worker 3"; user3.surname = "surname3";
    this.workers = [user1, user2, user3];
    this.workcentersService.getWorkcentersList().then(wc => this.centres = wc);
  }
}

這是測試:

import { ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
import { WorkcentersService } from 'app/services/workcenters.service';
import { Workcenter } from 'app/model/workcenter';
import { TestComponent } from './test.component';

fdescribe('TestComponent', () => {
  let component: TestComponent;
  let fixture: ComponentFixture<TestComponent>;

  beforeEach(async () => {
    const mockCentres = createMockCentres();
    const mockWorkcentersService = jasmine.createSpyObj(["getWorkcentersList"]);
    mockWorkcentersService.getWorkcentersList.and.returnValue(Promise.resolve(mockCentres));

    TestBed.configureTestingModule({
      declarations: [TestComponent],
      imports: [],
      providers: [
        { provide: WorkcentersService, useValue: mockWorkcentersService }
      ]
    });

    fixture = TestBed.createComponent(TestComponent);
    component = fixture.componentInstance;
    await fixture.whenStable();
    fixture.detectChanges();
  });

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

  // Passes
  it('should render users', async () => {
    const displayedUsers = fixture.nativeElement.querySelectorAll("ul li");
    expect(displayedUsers.length).toEqual(3);
  });

  // Fails
  it('should render centres', async () => {
    const displayedUsers = fixture.nativeElement.querySelectorAll("ol li");
    expect(displayedUsers.length).toEqual(2);
  });

  // Fails
  it('should display "hello"', fakeAsync(() => {
    fixture.detectChanges();
    tick();
    const displayedUsers = fixture.nativeElement.querySelectorAll("ol li");
    expect(displayedUsers.length).toEqual(2);
  }));

  function createMockCentres(): Workcenter[] {
    const mockCentre1 = new Workcenter();mockCentre1.id = 1;mockCentre1.name = "Test centre 1";
    const mockCentre2 = new Workcenter();mockCentre2.id = 2;mockCentre2.name = "Test centre 2";
    return [mockCentre1, mockCentre2];
  }
});
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';

import { AppComponent } from './app.component';
import { WorkCenter } from './workCenter';
import { WorkcentersService } from './workcenters.service';

fdescribe('TestComponent', () => {
  let component: AppComponent;
  let fixture: ComponentFixture<AppComponent>;
  let mockWorkcentersService: WorkcentersService;
  beforeEach(async () => {
    const mockCentres = createMockCentres();
    TestBed.configureTestingModule({
      declarations: [AppComponent],
      imports: [],
      providers: [
        WorkcentersService
      ]
    });

    fixture = TestBed.createComponent(AppComponent);
    mockWorkcentersService = TestBed.get(WorkcentersService);
    spyOn(mockWorkcentersService, 'getWorkcentersList').and.returnValue(new Promise((resolve, reject) => resolve(mockCentres)));
    component = fixture.componentInstance;
    await fixture.whenStable();
    fixture.detectChanges();
  });

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

  // Passes
  it('should render users', async () => {
    const displayedUsers = fixture.nativeElement.querySelectorAll('ul li');
    expect(displayedUsers.length).toEqual(3);
  });

  // Fails
  it('should render centres', async () => {
    expect(mockWorkcentersService.getWorkcentersList).toHaveBeenCalled();
    fixture.detectChanges();
    await fixture.whenStable();
    const displayedUsers = fixture.nativeElement.querySelectorAll('ol li');
    expect(displayedUsers.length).toEqual(2);
  });

  // Fails
  it('should display "hello"', fakeAsync(() => {
    fixture.detectChanges();
    tick();
    const displayedUsers = fixture.nativeElement.querySelectorAll('ol li');
    expect(displayedUsers.length).toEqual(2);
  }));

  function createMockCentres(): WorkCenter[] {
    const mockCentre1 = new WorkCenter(); mockCentre1.id = 1; mockCentre1.name = 'Test centre 1';
    const mockCentre2 = new WorkCenter(); mockCentre2.id = 2; mockCentre2.name = 'Test centre 2';
    return [mockCentre1, mockCentre2];
  }
});

這對我有用

證明:-

在此處輸入圖像描述

還嘗試運行單個測試用例來向您展示測試中心現在正在顯示:-

在此處輸入圖像描述

@Aakash Garg Ive 接受了您的回答,因為您做對了。

在花了(還)更多時間之后,我發現我們以不同方式創建間諜的事實並沒有任何區別。

關鍵事實是你轉過身來 fixture.detectChanges(); 等待fixture.whenStable(); 我有他們相反的方式。

您還在測試本身中添加了一個fixture.detectChanges(),這也是必要的。 附加的 whenStable 調用似乎沒有任何區別。

最后我使用了fixture.autoDetectChanges(),它在沒有fixture.whenStable調用的情況下工作,如下所示:

beforeEach(async () => {
    const mockCentres = createMockCentres();
    const workers = { workers: createMockWorkers(), companyId: 22 };
    const mockWorkcentersService = jasmine.createSpyObj(["getWorkcentersList"]);
    mockWorkcentersService.getWorkcentersList.and.returnValue(Promise.resolve(mockCentres));

    TestBed.configureTestingModule({
      declarations: [CentreAssociateComponent],
      imports: [],
      providers: [
        //WorkcentersService,
        { provide: WorkcentersService, useValue: mockWorkcentersService },
        { provide: MAT_DIALOG_DATA, useValue: workers },
        { provide: MatDialogRef, useValue: {} }
      ]
    });

    fixture = TestBed.createComponent(CentreAssociateComponent);
    fixture.autoDetectChanges();
    component = fixture.componentInstance;

    await fixture.whenStable();
  });

  it('should render centres', async () => {
    const displayedUsers = fixture.nativeElement.querySelectorAll("ol li");
    expect(displayedUsers.length).toEqual(2);
  });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM