Reputation: 1169
expectOne()
requires a URL string to match the request that the code under test makes via HttpClient
. But, I want separate tests for verifying the request URL and verifying the result data. I want one test to verify the request URL -- ignoring the result data -- which I can write. And I want another test to verify the result data -- regardless of the URL -- which I cannot write since expectOne
requires the URL parameter to match.
I searched for a way to tell expectOne
to ignore the URL or to match any URL, but found nothing. I did try passing '*'
, but that didn't work.
Is there a way to get HttpTestingController
to match any URL?
import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { OperationsLogService } from './operations-log.service';
import { Severity } from './severity.enum';
describe('OperationsLogService', () => {
let service: OperationsLogService;
let httpMock: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
HttpClientTestingModule
],
providers: [
OperationsLogService
]
});
service = TestBed.get(OperationsLogService);
httpMock = TestBed.get(HttpTestingController);
});
it('requests by page and max-count', (done) => {
service
.getEntries(3, 5)
.subscribe((res: any) => {
done();
});
const request = httpMock.expectOne('api/operations-log/oplog.json?page=3&max-count=5');
request.flush({});
httpMock.verify();
});
it('provides entries', (done) => {
const entries = [
{
severity: Severity.Informational,
whenLogged: Date.now(),
code: 123,
message: 'msg'
}
];
service
.getEntries(3, 5)
.subscribe((res: any) => {
expect(res).toEqual(entries);
done();
});
// don't want to specify the URL here
const request = httpMock.expectOne('api/operations-log/oplog.json?page=3&max-count=5');
request.flush(entries);
httpMock.verify();
});
});
Why I want this capability: Tests should be independent of each other. One issue/change should cause as few tests to fail as possible. If the URL test fails, then I don't want the other test (provides entries) to fail. One suggested that I store the URL in a common variable. That does eliminate code duplication, but the tests are still weak. If one fails (due to the URL changing), they both will fail.
Upvotes: 9
Views: 11574
Reputation: 171
There is an overload to expectOne()
that will do what you need (see the documentation at https://angular.io/api/common/http/testing/HttpTestingController#expectone):
abstract expectOne(matchFn: ((req: HttpRequest<any>) => boolean), description?: string): TestRequest
So for your test to match any URL, just return true
for every call to the match predicate:
const request = httpMock.expectOne(() => true);
request.flush(entries);
Upvotes: 13