【发布时间】:2017-03-22 02:34:47
【问题描述】:
我在 Angular 2 服务中有一个方法,它获取特定用户帐户的所有详细信息 - 已登录的用户帐户 - 并返回一个 Observable。
(我使用 AngularFire2 进行身份验证,物有所值)
如您所见,getData 方法使用了getAuth 方法,该方法返回身份验证状态(作为可观察对象),而getToken 方法(返回一个 Promise)又使用该方法来获取用于填充 Authorization 标头并执行 http 请求的令牌。 (我知道我的代码可能需要重构,如果有任何反馈,我将不胜感激)
getData(): Observable<IData> {
let authHeaders = new Headers();
return Observable.create((o: Observer<IData>) => {
this.getAuth().subscribe((authState: IState) => {
this.getToken(authState).then(token => {
/* ...
* Do things with that token, call an http service etc.
*/ ...
authHeaders.set('Authorization', token);
this.http.get('myendpoint/', {
headers: this.authHeaders
})
.map((response: Response) => response.json())
.map((data: IData) => {
o.next(data);
});
})
.catch((error: Error) => {
Observable.throw(new Error(`Error: ${error}`));
});
});
});
}
我是单元测试的新手,一直在尝试测试这种方法,但我仍然无法覆盖该方法中 Promise 的.catch。
这是我的单元测试的样子:
describe('Service: UserDataService', () => {
let mockHttp: Http;
let service: UserDataService;
let getAuthSpy: jasmine.Spy;
let getTokenSpy: jasmine.Spy;
beforeEach(() => {
mockHttp = { get: null } as Http;
TestBed.configureTestingModule({
providers: [
{ provide: Http, useValue: mockHttp },
AngularFire,
UserDataService,
]
});
service = new UserDataService(AngularFire, mockHttp);
spyOn(mockHttp, 'get').and.returnValue(Observable.of({
json: () => {
"nickname": "MockNickname"
}
}));
getAuthSpy = spyOn(service, 'getAuth').and.returnValue(Observable.of({
"auth": {
"uid": "12345"
}));
getTokenSpy = spyOn(service, 'getToken').and.returnValue(new Promise((resolve, reject) => {
resolve('test promise response');
}));
});
describe('getLead', () => {
beforeEach(() => {
spyOn(service, 'getLead').and.callThrough();
});
it('should return an object of user data and set the dataStore.userEmail if state exists', () => {
service.getLead().subscribe(res => {
expect(res).toEqual(jasmine.objectContaining({
nickname: 'MockNickname'
}));
});
expect(service.getLead).toHaveBeenCalled();
});
it('should throw, if no authState is provided', () => {
getAuthSpy.and.returnValue(Observable.of(false));
service.getLead();
expect(service.getLead).toThrow();
});
it('should throw, if getToken() fails to return a token', () => {
getTokenSpy.and.returnValue(new Promise((resolve, reject) => {
reject('test error response');
}));
/*
* This is where I am getting lost
*/
service.getLead();
expect(service.getLead).toThrow();
});
});
});
据我了解,我必须以某种方式从 getToken 拒绝该 Promise,并测试我的 observable 是否会抛出。
非常感谢任何帮助或反馈。
【问题讨论】:
-
spyOn(...).and.returnValue(Observable.throw(...).toPromise())?您可以使用Observable.map使其更加线性化,逐步而不是增加嵌套,根据需要转换fromPromise和toPromise。
标签: javascript unit-testing angular jasmine rxjs