【发布时间】:2017-08-09 12:03:01
【问题描述】:
我有这个代码:
/**
* Attempt login with provided credentials
* @returns {Observable<number>} the status code of HTTP response
*/
login(username: string, password: string): Observable<number> {
let body = new URLSearchParams();
body.append('grant_type', 'password');
body.append('username', username);
body.append('password', password);
let connObservable = this.http.post(Constants.LOGIN_URL, body, null)
.map(res => {
if (res.status == 200) {
log(res.json());
}
return res.status;
})
.catch(err => { return Observable.throw(err.status) })
.publish();
// this ensures that side effects will be present regardless os whether
// the client subscribes to the returned Observable
connObservable.connect();
// no need for the client to know that we use ConnectableObservable internally
return connObservable as Observable<number>;
}
我想用这段代码对它进行单元测试:
describe('AuthenticationService', () => {
let sut: AuthenticationService;
let authTokeServiceStub: AuthTokenServiceStub;
let mockBackend: MockBackend;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ HttpModule ],
providers: [
AuthenticationService,
{provide: XHRBackend, useClass: MockBackend},
{provide: AuthTokenService, useClass: AuthTokenServiceStub}
]
});
sut = TestBed.get(AuthenticationService);
authTokeServiceStub = TestBed.get(AuthTokenService);
mockBackend = TestBed.get(XHRBackend);
});
describe('login()', () => {
it('should store retrieved access token on successful response', () => {
mockBackend.connections.subscribe(connection => {
let options = new ResponseOptions();
options.body = JSON.stringify({access_token : 'accessToken'});
options.status = 200;
connection.mockRespond(new Response(options));
});
spyOn(authTokeServiceStub, 'setAuthToken');
sut.login('username', 'password');
expect(authTokeServiceStub.setAuthToken).toHaveBeenCalledWith('accessToken');
});
});
});
问题是log(res.json()) 总是产生空对象:{}。
为了隔离问题,我尝试将模拟响应的状态更改为 400,但没有任何效果。 Response 对象的 options 参数似乎被忽略了。
我尝试将测试包装在 async 中,然后在 fakeAsync 中并在阶段之间添加 tick() 和 tick(50),但它也不起作用。
我做错了什么?
【问题讨论】:
-
你能显示
AuthenticationService的@Component注解吗?还声明了@NgModule? -
您可以尝试在
mockBackend...subscribe()行之后的某处拨打tick();(import {tick} from '@angular/core/testing';) 吗? -
@acdcjunior,我已经尝试在不同的地方添加
async和fakeAsync和tick。还是行不通。此外,从调度的角度来看,看起来响应已发送并且一切正常。只是响应总是一个空响应,状态码为200,不管是怎么构造的…… -
如果你改变
option.status,它会反映在sut中吗? -
@acdcjunior nope
标签: angular unit-testing mocking