我对Angular4的世界相当新,并使用Jasmine / Karama进行测试。我创建了一个包含两个web api服务的小应用程序,我需要为这些服务编写测试。
使用在线示例,以及我对Angular4中模拟的基本理解,我已经设法破解了我的第一个服务及其运行正常的测试。第一个服务的构造函数只有一个依赖项(http模块,恰好与我正在使用的示例一致!)。
服务示例1 :
// Lookups api wrapper class.
@Injectable()
export class LookupsService {
private servicegApiUrl = '';
public constructor( private http : Http ) {
// Build the service api url, uring the environment lookups api url, plus controller name to reference.
this.servicegApiUrl = environment.apiUrl + 'Lookups/';
}
// Get the hubs from the web api.
public getHubs() : Observable<KeyValuePair<number>[]> {
// Carry out http get and map the result to the KeyValuePair number object.
return this.http.get(this.servicegApiUrl + 'Hubs').map(res => {
if (res){ return res.json() as KeyValuePair<number>[]; }
});
}
}
测试示例1 - 测试工作:
describe('Service: LookupService', () => {
let service: LookupsService;
let backend: MockBackend;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpModule],
providers: [
LookupsService,
MockBackend,
BaseRequestOptions,
{
provide: Http,
useFactory: (backend, options) => new Http(backend, options),
deps: [MockBackend, BaseRequestOptions]
}
]
});
// Get the MockBackend
backend = TestBed.get(MockBackend);
// Returns a service with the MockBackend so we can test with dummy responses
service = TestBed.get(LookupsService);
});
it('getHubs() should return populated KeyValuePair<number>[]', async(() => {
let response =
[{
"Key": "Hub 1 example",
"Value": 1
},{
"Key": "Hub 2 example",
"Value": 2
}]
;
// When the request subscribes for results on a connection, return a fake response
backend.connections.subscribe(connection => {
connection.mockRespond(new Response(<ResponseOptions>{
body: JSON.stringify(response)
}));
});
// Perform a request and make sure we get the response we expect
var hubsRes : KeyValuePair<number>[];
service.getHubs().subscribe(hubs => {
hubsRes = hubs;
console.log(hubs);
});
// Test hubs is populated.
expect(hubsRes.length).toBeGreaterThan(0);
}));
});
到目前为止一切顺利,我现在需要为第二项服务编写测试。在这个服务中,我注入了一个我为日志记录创建的自定义服务(它没有注入任何依赖项,只是包装console.log)。
服务示例2
// Routing Rules api wrapper class.
@Injectable()
export class RoutingRulesService {
private servicegApiUrl = '';
public constructor( private loggerService : LoggerService, private http : Http ) {
// Build the service api url, uring the environment routing api url, plus controller name to reference.
this.servicegApiUrl = environment.routingApiUrl + 'routingRules/';
}
// Perform search using passed in filter. Returns SearchResult object.
public getSearchFiltered(options): Observable<SearchResult> {
// Api url is the service url, plus Filtered and search query string.
var apiUrl = this.servicegApiUrl + 'Filtered' + options;
this.loggerService.logInfo("Route search query url: " + apiUrl);
// Carry out http get and map the result to the SearchResult object.
return this.http.get(apiUrl).map(res => {
if (res){ return res.json() as SearchResult; }
});
}
}
测试示例2 - 测试无法正常工作:
describe('Service: RoutingRulesService', () => {
let service: RoutingRulesService;
let logger : LoggerService;
let backend: MockBackend;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpModule, LoggerService],
providers: [
RoutingRulesService,
MockBackend,
BaseRequestOptions,
{
provide: Http,
useFactory: (backend, options) => new Http(backend, options),
deps: [MockBackend, BaseRequestOptions]
},
logger
]
});
// Get the MockBackend
backend = TestBed.get(MockBackend);
// Returns a service with the MockBackend so we can test with dummy responses
service = TestBed.get(RoutingRulesService);
});
it('getSearchFiltered(), with no search parameter, should return populated SearchResult', async(() => {
let response =
{
"Pagination": {
"RecordCount": 2,
"PageRecordsFrom": 1,
"PageRecordsTo": 1,
"TotalPages": 1,
"PageSize": 2,
"PageNumber": 1,
"SortBy": "RoutingRuleId",
"Ascending": true
},
"Results": [
{
"RoutingRuleId": 1,
"BrandId": 21,
"CashOnDelivery": false,
"CreationTime": "2017-09-11T15:14:41.207",
"CurrencyCode": 2,
"CurrencyDescription": "USD"
},
{
"RoutingRuleId": 2,
"BrandId": 21,
"CashOnDelivery": false,
"CreationTime": "2017-09-11T15:14:41.207",
"CurrencyCode": 2,
"CurrencyDescription": "USD"
}]
}
;
// When the request subscribes for results on a connection, return a fake response
backend.connections.subscribe(connection => {
connection.mockRespond(new Response(<ResponseOptions>{
body: JSON.stringify(response)
}));
});
// Perform a request and make sure we get the response we expect
var searchRes : SearchResult;
service.getSearchFiltered(null).subscribe(results => {
searchRes = results;
console.log(results);
});
// Test populated.
expect(searchRes.Pagination.RecordCount).toBeGreaterThan(0);
expect(searchRes.Results[0].RoutingRuleId).toEqual(1);
}));
});
编译测试时出现此错误:
服务:RoutingRulesService getSearchFiltered(),没有搜索参数,应返回已填充的SearchResult FAILED 错误:意外的值&#39; LoggerService&#39;由模块&#39; DynamicTestModule&#39;导入。请添加@NgModule注释。
如何成功将新记录器服务实例注入第二个服务?
提前感谢所有提示!