问题描述
我如何对这个登录功能进行单元测试,特别是 http post 部分?我制作的 http 模拟没有正确编码,无法进入代码的if...else"部分.我不想使用 TestBed.测试床太慢了.
How do I unit test this login function, specifically the http post part? The http mock I made is not coded correctly to get into the 'if...else' section of the code. I dont want to use TestBed. TestBed is too slow.
login(username: string, password: string): Observable<boolean> {
const headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('accept', 'application/json');
let options = new RequestOptions({ headers: headers });
return this.http.post('https://blah/api/login',
JSON.stringify({ username: username, password: password }), options)
.map((response: Response) => {
const token = response.json() && response.json().access_token;
if (token) {
this.token = token;
localStorage.setItem('currentUser', JSON.stringify({ username: username, token: token }));
return true;
} else {
return false;
}
}).catch(this._serverError);
}
private _serverError(err: any) {
return Observable.throw(err || 'backend server error');
}
下面是我尝试的 Jasmine 测试:我需要这方面的帮助.
Below is the Jasmine test Im attempting: I need help with this line.
spyOn(mockHttp,'post').and.returnValue(Observable.of(response));
我的 returnValue 应该是什么才能让我进入登录函数中的if...else"代码?
What should my returnValue be to get my inside of the 'if...else' code in the login function?
describe('AuthenticationService', () => {
let service: AuthenticationService;
let mockHttp = null;
beforeEach(() => {
mockHttp = {};
mockHttp.post = function(){};
service = new AuthenticationService(mockHttp);
});
it(`should set access token in local storage for successful login`,() => {
const access_token = 'blah83balc380';
const responseOptions = new ResponseOptions();
responseOptions.status = 200;
responseOptions.body = {access_token:access_token};
const username = 'test';
const currentUserExpected = JSON.stringify({ username: username, token: access_token });
var response = new Response(responseOptions);
spyOn(mockHttp,'post').and.returnValue(Observable.of(response));
service.login(username, 'test');
var currentUser = localStorage.getItem('currentUser');
expect(currentUserExpected).toEqual(currentUser);
});
});
推荐答案
这是我最终使用的答案.当我可以像下面的代码一样使用 TestBed 时,我以一种很慢的方式使用 TestBed:
This is the answer that I ended up using. I was using TestBed in a way that was slow when I could have been using TestBed like the code below:
import { TestBed, inject} from '@angular/core/testing';
import { HttpModule, XHRBackend, Response, ResponseOptions } from '@angular/http';
import { AuthenticationService } from '../_services/authentication.service';
import { MockBackend } from '@angular/http/testing';
describe('AuthenticationService', () => {
let mockbackend, service;
beforeEach(() => {
localStorage.clear();
TestBed.configureTestingModule({
imports: [ HttpModule ],
providers: [
AuthenticationService,
{ provide: XHRBackend, useClass: MockBackend }
]
});
});
beforeEach(inject([AuthenticationService, XHRBackend], (_service,
_mockbackend) => {
service = _service;
mockbackend = _mockbackend;
}));
it('should set access token in local storage for successful login', () =>
{
const access_token = 'blah83balc380';
const username = 'test';
const currentUserExpected = JSON.stringify({ username: username, token: access_token });
const response = {access_token: access_token};
const responseOptions = new ResponseOptions();
responseOptions.body = JSON.stringify(response);
mockbackend.connections.subscribe(connection => {
connection.mockRespond(new Response(responseOptions));
});
service.login(username, 'test').subscribe(respond => {
expect(respond).toEqual(true);
const currentUser = localStorage.getItem('currentUser');
expect(currentUserExpected).toEqual(currentUser);
});
});
it('should not set access token in local storage for unsuccessful login', () => {
const username = 'test';
const responseOptions = new ResponseOptions();
responseOptions.body = '';
responseOptions.status = 401;
const response = new Response(responseOptions);
response.ok = false;
response.statusText = 'Unauthorized';
response.type = 2;
mockbackend.connections.subscribe(connection => {
connection.mockRespond(response);
});
service.login(username, 'test').subscribe(respond => {
expect(respond).toEqual(false);
}, err => {
const currentUser = localStorage.getItem('currentUser');
expect(currentUser).toEqual(null);
});
});
});
这篇关于如何在不使用 TestBed 的情况下模拟 Angular 中的 http 帖子?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!