簡體   English   中英

如何在 Angular 2 中測試 *ngFor?

[英]How to test *ngFor in Angular 2?

我是 Angular 的新手並創建了待辦事項應用程序。 我試圖在許多地方甚至測試文檔中找到解決方案
我正在測試一個組件。 這帶來了來自 mongodb 的數據,不過我已經嘲笑了這些數據。

以下是模板的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

另外,當我只運行第一次測試時,我在瀏覽器上看不到任何東西。 它應該在瀏覽器上顯示任務!

那么這是否意味着 *ngFor 不會一次填充頁面上的內容.compileComponents(); 已被調用在 first beforeEach()生成 CSS 和 HTML ?

由於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是測試異步代碼時使用的首選方法。 fakeAsync作用是允許您像同步代碼一樣編寫代碼,並讓您控制何時完成異步測試。 一些測試代碼可能看起來像

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

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

  comp.callSomeAsyncMethod();
  tick();

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

暫無
暫無

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

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