问题描述
我正在从事Angular 5项目,这没什么大不了的.尽管从2.1/2.2初期开始我就退出了Angular2 +业务.
I'm working on a Angular 5 Project, it's nothing serious. Though I've been out of the Angular2+ business since early 2.1/2.2.
因此,我有此服务,该服务调用了公共API,但是我的测试始终失败:Error: Expected one matching request for criteria "Match URL: http://api.icndb.com/jokes/random/10", found none.
So I've got this Service which calls a public API, however my test keeps failing with: Error: Expected one matching request for criteria "Match URL: http://api.icndb.com/jokes/random/10", found none.
代码:
fact.service.spec.ts
fact.service.spec.ts
import {HttpClientTestingModule, HttpTestingController} from "@angular/common/http/testing";
import {TestBed, inject} from "@angular/core/testing";
import {FactService} from "./fact.service";
import {Fact} from "../models/fact";
import {FactHttpResponse} from "../models/factHttpResponse";
describe("FactService", () => {
let factService: FactService;
let httpMock: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [FactService],
});
httpMock = TestBed.get(HttpTestingController);
factService = TestBed.get(FactService);
});
// TODO: Something is going wrong with this test get some help online
it("Should be able to retrieve Facts in subscription when calling loadFacts", (done) => {
const factList: Fact[] = [
{id: 1, joke: "a"},
{id: 2, joke: "a"},
];
const factResponse: FactHttpResponse = { value: factList};
factService.subscribe(val => {
expect(val).toEqual(factList);
done();
});
const mockRequest = httpMock
.expectOne(factService.CHUCK_NORRIS_API.replace("{count}", "10"));
expect(mockRequest.request.method).toEqual('GET');
factService.loadFacts();
mockRequest.flush(factResponse);
});
afterEach(inject([HttpTestingController], (httpMock: HttpTestingController) => {
httpMock.verify();
}));
});
fact.service.ts
fact.service.ts
import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Subject } from "rxjs/Subject";
import {Fact} from "../models/fact";
import {FactHttpResponse} from "../models/factHttpResponse";
@Injectable()
export class FactService {
// public for testing purposes
public readonly CHUCK_NORRIS_API = "http://api.icndb.com/jokes/random/{count}";
private factSubject = new Subject();
private facts: Fact[] = [];
private favorites: Fact[] = [];
constructor(private http: HttpClient) { }
public subscribe(callback: (value: Fact[]) => void) {
return this.factSubject.subscribe(callback);
}
public loadFacts(count = 10) {
this.http.get<FactHttpResponse>(this.CHUCK_NORRIS_API.replace("{count}", count.toString()))
.subscribe(data => {
if (data.value) {
this.facts = data.value
.map(f => {
f.favorite = !!this.favorites.find(fav => fav.id === f.id);
return f;
});
this.factSubject.next(this.facts);
}
});
}
}
该代码实际上有效,但我似乎无法对其进行测试:-(..如果我删除了verifyOne,它实际上会抱怨对错误提到的完全相同的URL的打开请求.
The code actually works, but I can't seem to test it :-(. If I remove the verifyOne it actually complains about an open request to the exact same url mentioned in error.
推荐答案
由于是您的方法factService.loadFacts()
生成了HTTP请求,因此您的测试的最后三部分是乱序的.应该是(带有注释):
Since it is your method factService.loadFacts()
that is generating the HTTP request, you have the last three pieces of your test out of order. It should be (with comments):
describe(..., () => {
it(..., () => {
...
// queue up the http request in the mockHttp request queue
factService.loadFacts();
// verify that there is now one (and only one) request queued up
const mockRequest = httpMock
.expectOne(factService.CHUCK_NORRIS_API.replace("{count}", "10"));
expect(mockRequest.request.method).toEqual('GET');
// satisfy the pending request in the mockHttp request queue
mockRequest.flush(factResponse);
});
// Bonus tip: you already have mockHttp in the describe() scope. Simplify:
afterEach(() => {
// verify there are no unsatisfied requests in the mockHttp queue
httpMock.verify();
});
});
这篇关于Angular使用HttpClient测试服务对我不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!