angular2单元测试:无法读取componentInstance.method()未定义的属性

前端之家收集整理的这篇文章主要介绍了angular2单元测试:无法读取componentInstance.method()未定义的属性前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
mycomponent.spec.ts类:

抛出错误:无法读取未定义的属性“ngOnInit”.

let myComponent: MyComponent;
let myService: MyService;

describe('myComponent',() => {
   beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [MyComponent],providers: [
      {provide: MyService,useClass: MockMyService} // **--passing Mock service**
  ]
}).compileComponents()
  .then(() => {
    myComponent = TestBed.createComponent(MyComponent).componentInstance;
    myService = TestBed.get(MyService);
    console.log(myService.getData());
  });
});

it('should get the mock data',() => {
   myComponent.ngOnInit(); //-----------> seems like myComponent is not defined at this place,how to resolve this error 
   expect(myComponent.data).toBe(DATA_OBJECT);
  });
});

下面是MyComponent:

@Component({
  selector: 'pm-catalogs',templateUrl: './catalog-list.component.html'
})

export class MyComponent implements OnInit {

 public data: IData[];

 constructor(private _myService: MyService) {

}

public ngOnInit(): void {
this._myService.getData()
  .subscribe(
    data => this.data = data
  //  error => this.errorMessage = <any>error
  );
 }
}

下面是模拟服务

export const DATA_OBJECT: IData[] = [
 {
   'Id': 1,'value': 'abc'
 },{
'Id': 2,'value': 'xyz'
 }];

@Injectable()
export class MockMyService {
 public getData(): Observable<IData[]> {
    return Observable.of(DATA_OBJECT);
  }
}

我是Angular2测试的新手,当myComponent.ngOnInit()在我的spec类中调用myService.getData()方法时,我希望myService.getData返回DATA_OBJECT
请帮助我实现这一目标.

解决方法

问题是异步beforeEach被错误地实现,这导致竞争条件.

在beforeEach块中执行.compileComponents().then(()=> {…})导致延迟代码执行,然后回调至少一个tick.它块永远不会等待并在有机会被分配之前访问myComponent变量.

当测试没有失败时,这种竞争条件会变得不那么明显,也会变得更加危险.相反,当之前的测试中的每个测试影响当前测试中的变量时,测试可能会变得交叉污染.

.compileComponents()是同步的,除非有使用styleUrls和templateUrl的组件(如上例所示).在这种情况下,它变为异步,应该使用async helper:

// asynchronous block
beforeEach(async(() => {    
  TestBed.configureTestingModule({ ... })
  .compileComponents();
}));

// synchronous block
beforeEach(() => {    
  myComponent = ...
});

根据经验,如果块可能是异步的,那么块应该使用fakeAsync helper的异步包装.

使用TestBed测试组件类时,它们遵循生命周期并自动调用它们的钩子.不需要手动调用ngOnInit()(如另一个答案所示)并将导致调用挂钩两次.

猜你在找的Angularjs相关文章