对于使用Service I'am的组件编写单元测试 - spec文件。
组件中的功能:
registerUser(email: string, pass: string) {
if (!this.EMAIL_REGEXP.test(email)) {
return false;
} else if (!this.PASS_REGEXP.test(pass)) {
return false;
} else {
this._backUpApiService.storeUserData(email, pass)
.subscribe(
(res) => {
console.log(JSON.stringfy(res));
...
},
(err) => {
console.log(JSON.stringfy(err));
...
}
);
}
}
服务中的方法:
storeUserData(email:String, pass:String) {
this.form = this._fbuilder.group({
input: {
user:{
umail:email,
upassword:pass
}
}
});
let formObj = this.form.getRawValue();
let serializedObj = JSON.stringify(formObj);
return this._http.post(url, serializedObj, this.options)
.map(res => {
res.json();
})
.catch((error: any) => Observable.throw(error.json().error || 'Server error'));
}
规范文件:
it(`should call storeUserData on BackendApiService when registerUser is called with correct Credentials`, async(() => {
let myService: BackendApiService = new BackendApiService();
spyOn(myService, 'storeUserData').and.returnValue(Observable.of(myService));
const emailOk = [
'test@test.com',
'test@test.co.uk',
];
const passwordOk = '!cdRef2';
let result = component.registerUser(this.emailOk, this.passwordOk);
expect(myService.storeUserData).toHaveBeenCalled();
}));
问题是测试失败,我不断收到以下信息: Cannot read property 'parseUrl' of undefined
规范文件中的函数是否期望服务函数中的Ajax调用的 URL
?我实际上只想测试在调用/调用组件中的 storeUserData
函数时是否正在调用服务中的 registerUser
函数。
我做错了什么?
答案 0 :(得分:1)
我不知道为什么你得到一个“无法读取属性'parseUrl'的未定义”错误,因为你的代码不包含对parseUrl的任何引用。
但是我可以看到一些错误:
第一个storeUserData实际上并没有从registerUser调用addUser是。
第二个registerUser期望传递一个字符串,就像它的电子邮件一样,你传递一个字符串数组。
修改强>
另外一个观察:
另一个错误的地方是您正在创建服务的新实例,而不是获取组件使用的服务实例。你需要使用:
const myService = TestBed.get(BackendApiService);
然后,您将实际监视组件使用的服务实例。这当然会假设您的服务被注入到组件的构造函数中。
如果你让spyOn正常工作,那么你确实不必担心storeUserData会发生什么,因为它永远不会被调用。错误可能来自唯一的另一个地方是您的服务的构造函数。我已创建服务存根类以注入我的测试,以便我的服务类依赖不会导致问题。对于你可能看起来像:
export class BackendApiServiceStub {
storeUserData(email: String, pass: String) {
return Observable.of([]);
}
}
然后你需要在测试条中用存根替换真实的东西,如下所示:
TestBed.configureTestingModule({
declarations: [
AppComponent
],
providers: [
{provide: BackendApiService, useClass: BackendApiServiceStub }
]
}).compileComponents();
这应该可以阻止任何其他问题蔓延到您的测试中。