Dae*_*esi 5 unit-testing jasmine typescript karma-jasmine angular
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);
});
});
Run Code Online (Sandbox Code Playgroud)
以下是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
);
}
}
Run Code Online (Sandbox Code Playgroud)
下面是模拟服务
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);
}
}
Run Code Online (Sandbox Code Playgroud)
我是Angular2测试的新手,当myComponent.ngOnInit()调用我的规范类中的myService.getData()方法时,我希望myService.getData返回DATA_OBJECT,请帮助我实现这一点。
问题是异步beforeEach实现不正确,这会导致竞争条件。
做.compileComponents().then(() => { ... })在beforeEach块导致在延迟代码执行then回调至少为一个刻度。it块myComponent在有机会被分配之前从不等待并访问变量。
当测试没有失败时,这种竞争条件会变得不那么明显和更危险。相反,当beforeEach以前的测试影响当前测试中的变量时,测试可能会受到交叉污染。
.compileComponents()是同步的,除非有带有styleUrls和的组件templateUrl(就像上面的例子)。在这种情况下,它变成异步的,async应该使用 helper:
// asynchronous block
beforeEach(async(() => {
TestBed.configureTestingModule({ ... })
.compileComponents();
}));
// synchronous block
beforeEach(() => {
myComponent = ...
});
Run Code Online (Sandbox Code Playgroud)
根据经验,如果块有可能是异步的,块应该用asyncof fakeAsynchelper包装。
当使用 测试组件类时TestBed,它们遵循一个生命周期并自动调用它们的钩子。ngOnInit()不需要手动调用(正如另一个答案所解释的那样)并且会导致两次调用挂钩。