我想知道对这个简单函数进行100%覆盖的确切方法,但似乎无法做到正确。
命名-list.service.ts
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
// import 'rxjs/add/operator/do'; // for debugging
/**
* This class provides the NameList service with methods to read names and add names.
*/
@Injectable()
export class NameListService {
/**
* Creates a new NameListService with the injected Http.
* @param {Http} http - The injected Http.
* @constructor
*/
constructor(private http: Http) {}
/**
* Returns an Observable for the HTTP GET request for the JSON resource.
* @return {string[]} The Observable for the HTTP request.
*/
get(): Observable<string[]> {
return this.http.get('assets/data.json')
.map((res: Response) => res.json())
// .do(data => console.log('server data:', data)) // debug
.catch(this.handleError);
}
/**
* Handle HTTP error
*/
private handleError (error: any) {
// In a real world app, we might use a remote logging infrastructure
// We'd also dig deeper into the error to get a better message
let errMsg = (error.message) ? error.message :
error.status ? `${error.status} - ${error.statusText}` : 'Server error';
console.error(errMsg); // log to console instead
return Observable.throw(errMsg);
}
}
和当前的单元测试
命名-list.service.spec.ts
import { BaseRequestOptions, ConnectionBackend, Http, Response, ResponseOptions } from '@angular/http';
import { TestBed, async } from '@angular/core/testing';
import { MockBackend } from '@angular/http/testing';
import { Observable } from 'rxjs/Observable';
import { NameListService } from './name-list.service';
export function main() {
describe('NameList Service', () => {
let nameListService: NameListService;
let mockBackend: MockBackend;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
NameListService,
MockBackend,
BaseRequestOptions,
{
provide: Http,
useFactory: (backend: ConnectionBackend, options: BaseRequestOptions) => new Http(backend, options),
deps: [MockBackend, BaseRequestOptions]
}
]
});
});
it('should return an Observable when get called', async(() => {
expect(TestBed.get(NameListService).get()).toEqual(jasmine.any(Observable));
}));
it('should resolve to list of names when get called', async(() => {
let nameListService = TestBed.get(NameListService);
let mockBackend = TestBed.get(MockBackend);
mockBackend.connections.subscribe((c: any) => {
c.mockRespond(new Response(new ResponseOptions({ body: '["Dijkstra", "Hopper"]' })));
});
nameListService.get().subscribe((data: any) => {
expect(data).toEqual(['Dijkstra', 'Hopper']);
});
}));
beforeEach(function(){
spyOn(console, 'error');
})
it('should throw an Observable when get called', (() => {
let nameListService = TestBed.get(NameListService);
let err = {
message: "Some error", status: 500, statusText: "Some error text"
};
expect(nameListService.handleError(err)).toEqual(jasmine.any(Observable))
}));
});
}
如何测试 errMsg 变量和 console.error 以获得100%的覆盖率?
答案 0 :(得分:1)
这应该逐行测试,就像它总是在单元测试中一样。
如果它是一个回调函数,它的调用应该与它应该完全相同,即没有上下文。
it('should throw an Observable when get called', fakeAsync(() => {
...
const errObservable = nameListService.handleError.call(null, err);
expect(console.error).toHaveBeenCalledWith('Some error');
expect(errObservable).toEqual(jasmine.any(Observable));
errObservable.toPromise().then(
() => { throw new Error('shouldn't be resolved') }),
errMsg => {
expect(errMsg).toBe('Some error');
})
);
}));
然后对没有err
属性的message
对象执行相同的操作。
toPromise
在这里很有用,因为如果observable为空,它将无法通过测试,而subscribe
永远不会被触发。