I am practising the Integration workbook provided by salesforce. In tutorial#2 there's a class which makes future callouts to a Heroku app.This class is called by an after update trigger. Callout class:
public class UpdateHeroku {
public class ExternalOrder{
public string id{get;set;}
public Integer order_number{get;set;}
}
@future(callout=true)
public static void postOrder(list<id> invoiceids){
JSONGenerator gen = Json.createGenerator(true);
gen.writeStartArray();
for(id invoiceid:invoiceids){
gen.writeStartObject();
gen.writeStringField('id', invoiceid);
gen.writeEndObject();
}
gen.writeEndArray();
string jsonOrders = gen.getAsString();
System.debug('jsonOrders: '+ jsonOrders);
HTTPrequest req = new HTTPrequest();
req.setMethod('POST');
req.setEndpoint('https://dry-springs-6303.herokuapp.com');
req.setHeader('Content-Type', 'application/json');
req.setBody(jsonOrders);
req.setTimeout(30000);
Http http = new Http();
HttpResponse res = http.send(req);
System.debug('Fulfillment service returned '+ res.getBody());
if(res.getStatusCode()!=200){
System.debug('Error from '+ req.getEndpoint() + ':'+ res.getStatusCode() + ' ' + res.getStatus());
}
else
{
list<invoice__c> invoices = [select id from Invoice__c where id in :invoiceids];
list<externalorder> orders = (list<ExternalOrder>)JSON.deserialize(res.getBody(), list<ExternalOrder>.class);
Map<Id, Invoice__c> invoiceMap = new Map<Id, Invoice__c>(invoices);
for(externalorder order:orders){
Invoice__c invoice = invoiceMap.get(order.id);
invoice.orderid__c = String.valueOf(order.order_number);
}
update invoices;
}
}
}
I have written a test class for trigger which covers 62% of the callout class. I am figuring a way to separately unit test the callout class & wrote an implementation of mock interface
Test Class- which lead to code coverage of 66%
@isTest
public class UpdateHeroku_Test {
@isTest static void testCallout(){
Test.setMock(HttpcalloutMock.class, new MockGenerator_Test());
list<invoice__c> invoices = new list<invoice__c>();
list<id> invoiceids = new list<id>();
invoices.add(new invoice__c(status__c='Negotiating'));
invoices.add(new invoice__c(status__c='Pending'));
insert invoices;
invoices[0].status__c = 'Closed';
invoices[1].status__c = 'Closed';
update invoices;
invoiceids.add(invoices[0].id);
invoiceids.add(invoices[1].id);
Test.startTest();
UpdateHeroku.postOrder(invoiceids);
Test.stopTest();
System.assertEquals(expected1, invoice[0].orderid__c);
System.assertEquals(expected2, invoice[1].orderid__c);
}
global class MockGenerator_Test implements HttpCalloutMock{
global httpResponse respond(HTTPrequest req){
System.assertEquals('https://dry-springs-6303.herokuapp.com', req.getEndpoint());
System.assertEquals('POST', req.getMethod());
HttpResponse res = new HttpResponse();
res.setHeader('Content-Type', 'application/json');
res.setStatusCode(405);
res.setStatus('Method Not Allowed');
return res;
}
}
}
Since future methods can only return void type. I can't verify values received in HttpResponse using assertEquals method. Something like below which I intend to -
String contentType = res.getHeader('Content-Type');
System.assert(contentType == 'application/json');
String actualValue = res.getBody();
String expectedValue = '{"foo":"bar"}';
System.assertEquals(actualValue, expectedValue);
How can I verify the response returned? Thanks,