[英]Unit testing $q promise within Angular service - Karma, Jasmine
[英]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.