Skip to content

Instantly share code, notes, and snippets.

@rsoesemann
Last active June 1, 2021 13:20
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rsoesemann/2b70adab297e00e5812ab5590875e4cc to your computer and use it in GitHub Desktop.
Save rsoesemann/2b70adab297e00e5812ab5590875e4cc to your computer and use it in GitHub Desktop.
apex-http-mock
@IsTest
public class HttpMock implements HttpCalloutMock {
private static final String ANY_URL = null;
private Map<String, Map<String, Object>> responses = new Map<String, Map<String, Object>>();
// PUBLIC
public HttpMock get(String url, Object body, Integer statusCode) {
return mock('GET', url, body, statusCode);
}
public HttpMock get(String url, Object body) {
return get(url, body, 200);
}
public HttpMock get(Object body, Integer statusCode) {
return get(ANY_URL, body, 200);
}
public HttpMock post(String url, Object body, Integer statusCode) {
return mock('POST', url, body, statusCode);
}
public HttpMock post(String url, Object body) {
return post(url, body, 200);
}
public HttpMock post(Object body, Integer statusCode) {
return post(ANY_URL, body, 200);
}
public HttpMock put(String url, Object body, Integer statusCode) {
return mock('PUT', url, body, statusCode);
}
public HttpMock put(String url, Object body) {
return put(url, body, 200);
}
public HttpMock put(Object body, Integer statusCode) {
return put(ANY_URL, body, 200);
}
public void mock() {
Test.setMock(HttpCalloutMock.class, this);
}
// implements HttpCalloutMock
public HttpResponse respond(HttpRequest request) {
HttpResponse result = badRequest();
String method = request.getMethod();
if(responses.containsKey(method)) {
for(String url : responses.get(method).keySet()) {
if(url == ANY_URL || request.getEndpoint().containsIgnoreCase(url)) {
Object response = responses.get(method).get(url);
if(response instanceof Exception) {
throw (Exception) response;
}
else {
result = (HttpResponse) response;
}
break;
}
}
}
return result;
}
// PRIVATE
private HttpMock mock(String method, String url, Object body, Integer statusCode) {
if(!responses.containsKey(method)) {
responses.put(method, new Map<String, Object>());
}
if(body instanceof Exception) {
responses.get(method).put(url, body);
}
else {
HttpResponse response = new HttpResponse();
response.setHeader('Content-Type', 'application/json');
response.setStatusCode(statusCode);
response.setBody(JSON.serialize(body));
responses.get(method).put(url, response);
}
return this;
}
private HttpMock mock(String method, String url, Object body) {
return mock(method, url, body, 200);
}
private HttpMock mock(String method, Object body, Integer statusCode) {
return mock(method, ANY_URL, body, 200);
}
private HttpResponse badRequest() {
HttpResponse result = new HttpResponse();
result.setStatusCode(500);
result.setStatus('Invalid Request');
result.setBody('{}');
return result;
}
}
@IsTest
private class HttpMock_Test {
private static final PersonApi API = new PersonApi();
private static final Person JOE = new Person('joe');
private static final Person TIM = new Person('tim');
@IsTest
private static void multipleEndpointFragments() {
// Setup
new HttpMock()
.get('/v2/persons', new List<Person>{ JOE, TIM },200)
.get('/v2/person/tim', TIM, 200)
.mock();
// Exercise + Verify
Test.startTest();
System.assertEquals(2, API.getPersons().size());
System.assertEquals('tim', API.getPerson('tim').name);
Test.stopTest();
}
@IsTest
private static void multipleHttpMethods() {
// Setup
new HttpMock()
.get('/v2/person/tim', TIM, 200)
.post('/v2/person/tim', true, 200)
.mock();
// Exercise + Verify
Test.startTest();
System.assertEquals(true, API.updatePerson(new Person('tim')) );
System.assertEquals('tim', API.getPerson('tim').name);
Test.stopTest();
}
@IsTest
private static void fail() {
// Setup
new HttpMock()
.get('/v2/persons', new CalloutException())
.mock();
// Exercise + Verify
try {
Test.startTest();
API.getPersons();
Test.stopTest();
System.assert(false);
}
catch(CalloutException ex) {
System.assert(true);
}
}
// HELPER
private class PersonApi {
public List<Person> getPersons() {
HttpRequest request = new HttpRequest();
request.setEndpoint('/v2/persons');
request.setMethod('GET');
return (List<Person>) JSON.deserialize(new Http().send(request).getBody(), List<Person>.class);
}
public Person getPerson(String name) {
HttpRequest request = new HttpRequest();
request.setMethod('GET');
request.setEndpoint('/v2/person/'+name);
return (Person) JSON.deserialize(new Http().send(request).getBody(), Person.class);
}
public Boolean updatePerson(Person person) {
try {
HttpRequest request = new HttpRequest();
request.setMethod('POST');
request.setEndpoint('/v2/person/'+person.name);
new Http().send(request);
}
catch(Exception ex){
return false;
}
return true;
}
}
private class Person {
public String name;
public Person(String name) {
this.name = name;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment