【问题标题】:How to test *ngFor in Angular 2?如何在 Angular 2 中测试 *ngFor?
【发布时间】:2017-07-23 00:42:51
【问题描述】:

我是 Angular 的新手并创建了待办事项应用程序。我试图在很多地方找到解决方案,即使是Testing documentation
我正在测试一个组件。从 mongodb 带来数据,不过我已经模拟了这些数据。

以下是模板的HTML(使用引导程序):

<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 就不会填充页面上的内容?

【问题讨论】:

  • 从 '@angular/platform-b​​rowser' 导入 { By };

标签: unit-testing angular karma-jasmine


【解决方案1】:

由于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。除非测试发出 XHR 请求,而 fakeAsync 无法处理,否则 fakeAsync 是测试异步代码时首选的方法。 fakeAsync 所做的是允许您编写代码,就好像它是同步的一样,并让您控制何时完成异步测试。一些测试代码可能看起来像

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

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

  comp.callSomeAsyncMethod();
  tick();

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

【讨论】:

  • 每次我都会忘记“whenStable”:)
猜你喜欢
  • 2017-09-20
  • 2018-02-06
  • 2018-06-11
  • 2016-06-22
  • 1970-01-01
  • 2021-09-29
  • 2017-02-22
  • 2018-03-24
  • 2017-01-13
相关资源
最近更新 更多