Created
June 25, 2019 19:45
-
-
Save jjrasche/af6b6dbe3dac8ccfa5ce7da873298715 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Angular | |
import { HttpRequest } from "@angular/common/http"; | |
import { HttpTestingController, TestRequest } from "@angular/common/http/testing"; | |
import { async, TestBed } from "@angular/core/testing"; | |
// Models | |
import { HttpMockModel } from "./http-mock.model"; | |
// tslint:disable: max-line-length | |
export class BaseHttpTest { | |
public defaultMockResponses: Array<HttpMockModel>; | |
public httpMock: HttpTestingController; | |
public settings: HttpTestingSettings = { | |
verifyAllCalls: true | |
}; | |
// overwritten by implementation | |
public wait: () => void; | |
protected setupHttpMock(): void { | |
beforeEach(async(() => { | |
this.httpMock = TestBed.get(HttpTestingController); | |
})); | |
afterEach(() => { | |
if (this.settings.verifyAllCalls) { | |
this.httpMock.verify(); | |
} | |
}); | |
} | |
public expectSingleRequest(match: (req: HttpRequest<any>) => boolean, response: any = null): HttpRequest<any> { | |
const saveRequest = new HttpMockModel( | |
(req: HttpRequest<any>) => { | |
return match(req); | |
}, response); | |
return this.waitAndRespondToRequest([saveRequest]); | |
} | |
/** | |
* Expects some particular http request, does not require that it is the only request | |
*/ | |
public expectRequest(match: (req: HttpRequest<any>) => boolean, response: any = null) { | |
this.wait(); | |
const testRequest = this.httpMock.match(match); | |
if (testRequest.length === 0) { | |
throw new Error("No requests were found matching the request type."); | |
} | |
if (testRequest.length > 1) { | |
throw new Error("More than 1 request found mathing the given criteria."); | |
} | |
testRequest[0].flush(response); | |
this.wait(); | |
} | |
public waitAndRespondToRequest(mocks: Array<HttpMockModel> = null): HttpRequest<any> { | |
if (!mocks && !this.defaultMockResponses) { | |
throw new Error("Must specify default mock responses if calling 'waitAndRespondToRequest' without argument"); | |
} | |
this.wait(); // wait for requests to go out | |
const req = this.listenAndRespondToMockHttpCalls(mocks ? mocks : this.defaultMockResponses); | |
this.wait(); // wait for results to get loaded | |
return req; | |
} | |
public listenAndRespondToMockHttpCalls(httpMocks: Array<HttpMockModel>): HttpRequest<any> { | |
let req: TestRequest; | |
httpMocks.forEach((mock: HttpMockModel) => { | |
req = this.httpMock.expectOne(mock.match); | |
req.flush(mock.response); | |
}); | |
return req.request; | |
} | |
public flushAllRequests() { | |
const allRequests = this.httpMock.match((req: HttpRequest<any>) => true); | |
allRequests.forEach(req => req.flush({data : {}})); | |
} | |
/** | |
* | |
* @param urlSuffix | |
* @param expectedVerb | |
* @param expectedBody | |
* @param shouldError in scenarios where it is ok to have multiple requests, this method is used to determine which of the multiple | |
* requests match criteria, therefore all but one request will likely fail and should not throw an error. | |
*/ | |
public verifyRequest(urlSuffix: string = null, expectedVerb: "GET" | "POST" | "PUT" | "DELETE" = null, expectedBody: any = null, shouldError: boolean = true): (req: HttpRequest<any>) => boolean { | |
return (req: HttpRequest<any>) => { | |
if (!urlSuffix && !expectedVerb && !expectedBody) { | |
console.error("Intentionally performing a mock service call without verifying url matchs. I hope you know what you're doing"); | |
return true; | |
} | |
const expectedUrl = `test${urlSuffix}`; | |
const actualUrl = req.url; | |
if (expectedUrl !== actualUrl) { | |
if (shouldError) { | |
throw new Error(`Expected url ${actualUrl} to equal ${expectedUrl}.`); | |
} | |
return false; | |
} | |
const actualVerb = req.method; | |
if (!!expectedVerb && expectedVerb !== actualVerb) { | |
if (shouldError) { | |
throw new Error(`Expected verb ${actualVerb} to equal ${expectedVerb}.`); | |
} | |
return false; | |
} | |
const actualBodyString = JSON.stringify(req.body); | |
const expectedBodyString = JSON.stringify(expectedBody); | |
if (!!expectedBody && expectedBodyString !== actualBodyString) { | |
if (shouldError) { | |
throw new Error(`Expected body ${actualBodyString} to equal ${expectedBodyString}.`); | |
} | |
return false; | |
} | |
return true; | |
}; | |
} | |
} | |
export interface HttpTestingSettings { | |
verifyAllCalls: boolean; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment