2017-03-03 151 views
3

我是Angular的新手,并创建待办事宜应用程序。我试图在很多地方找到解决方案,即使是我正在测试组件的情况下也是如此。这从MongoDB中获取数据,但我嘲笑了这些数据。
如何在Angular 2中测试* ngFor?

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

另外,我没有看到任何浏览器时,我只运行一次考验。它应该在浏览器上显示任务!

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

+1

import {By} from @ angular/platform-b​​rowser'; –

回答

3

由于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')); 
    ... 
}) 
+0

它不适合我!有任何想法吗 ? – Luillyfe