gpt4 book ai didi

unit-testing - 如何在 Angular 2 中测试 *ngFor?

转载 作者:太空狗 更新时间:2023-10-29 17:19:10 25 4
gpt4 key购买 nike

我是 Angular 的新手,我创建了 To-Do 应用程序。我试图在许多地方找到解决方案,甚至是 Testing documentation
我正在测试一个组件。从 mongodb 中获取数据,不过我已经 mock 了该数据。

以下是模板的HTML(使用bootstrap):

<li class="list-group-item" *ngFor="let task of tasks">
<div class=" task-date">{{task.date}}</div>
</li>

下面是组件代码(我只添加了子部分):

export class ShowTaskComponent extends OnInit{

tasks:Task[];

ngOnInit() {
setInterval(() => {this.refreshTasks()}, 3000);
}

constructor(private appService: AppService, private _router:Router){
super();
this.refreshTasks();
}

refreshTasks = function() {

this.appService.retrieveDataFromServer().subscribe((data: any) => {

//this.appService.taskArray = data;

this.tasks = data;

});

};
}

现在我正在添加测试代码(.spec.ts 文件的子部分)......为了解释清楚,所有代码(不包括导入):

  let comp: ShowTaskComponent;
let fixture: ComponentFixture<ShowTaskComponent>;
let service: AppService;
let router: Router;

let debugTaskTitle: DebugElement[];
let taskTitles: any[];

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ShowTaskComponent],
providers: [AppService],
imports: [....]
})
.compileComponents();
}));

beforeEach( () => {

fixture = TestBed.createComponent(ShowTaskComponent);
service = fixture.debugElement.injector.get(AppService);
router = fixture.debugElement.injector.get(Router);

let dummyTasks: any[] = [
{
"date": "12 October 2017",
"title": "Demo task 1",
"description": "Demo task 1 desc",
"priority" : "High",
"_id" : "1"
},
{
"date": "1 January 2018",
"title": "Demo task 2",
"description": "Demo task 2 desc",
"priority" : "Low",
"_id" : "2"
}
];

spyOn(service, 'retrieveDataFromServer').and.returnValue(Observable.of<any[]>(dummyTasks));


fixture = TestBed.createComponent(ShowTaskComponent);
comp = fixture.componentInstance;
console.log("----------------------------> comp ", comp);

debugTaskTitle = fixture.debugElement.queryAll(By.css('div.task-title'));
console.log("----------------------------> debugTaskTitle ", debugTaskTitle);

let counter: number = 0;

for(let title of debugTaskTitle) {
taskTitles.push(title.nativeElement);
taskTitles[counter].innerText = dummyTasks[counter].title;
counter ++;
}
});

//This test fails because taskTitles is undefined!
it('test whether a correct test has loaded', () =>{

expect(taskTitles).toBe(["Demo task 1", "Demo task 2"]);
});

问题来自 debugTaskTitle。这是一个空数组,当我尝试用 fixture.debugElement.queryAll(By.css()) 初始化它时。

我试图在控制台上打印它(看长 --------> 箭头),它是一个空数组。

组件 comp 的对象已创建并且运行良好。

谁能告诉我哪里错了?我迟到了三天才提交这份作业。任何帮助都会很棒。

完整代码位于 github repo

另外,当我只运行第一个测试时,我在浏览器上看不到任何东西。它应该在浏览器上显示任务!

这是否意味着一旦 .compileComponents(); 被调用以在第一个 beforeEach() 中生成 CSS 和 HTML,*ngFor 就不会填充页面上的内容?

最佳答案

由于 retrieveDataFromServer 返回一个 Observable,您需要等待异步任务解决。为此,您可以将 beforeEach 包装在 async 中,就像上面的一样。然后就需要等它稳定了

fixture = TestBed.createComponent(ShowTaskComponent);
comp = fixture.componentInstance;

fixture.whenStable().then(() => {
// after something in the component changes, you should detect changes
fixture.detectChanges();

// everything else in the beforeEach needs to be done here.
debugTaskTitle = fixture.debugElement.queryAll(By.css('div.task-title'));
...
})

更新

请注意,现在建议使用 fakeAsync 而不是 async。除非测试发出 fakeAsync 无法处理的 XHR 请求,否则 fakeAsync 是测试异步代码时使用的首选方法。 fakeAsync 的作用是让您编写代码就像它是同步的一样,并让您控制何时完成异步测试。一些测试代码可能看起来像

import { fakeAsync } from '@angular/core/testing';

it('should...', fakeAsync(() => {
fixture = TestBed.createComponent(ShowTaskComponent);
comp = fixture.componentInstance;

comp.callSomeAsyncMethod();
tick();

fixture.detectChanges();
// assertions
}));

关于unit-testing - 如何在 Angular 2 中测试 *ngFor?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42569836/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com