You need to sign in to do that
Don't have an account?
venkatesh kotapati
Not able to acheive 100% code coverage using schedule class which calls webservice asynchronously
Requirement
apex class calls webservice to retrieve product information. I have to schedule this class to run at night 10 pm everyday and write test class for the callout.
Solution:
I have written apex class which does the callout and upsert product object. Since I have to schedule this update i called the apex class from schedule class. As I cannot do synchronous callouts in schedule apex i have made the method as asychronous(@future) (asynchronous methods has no return type). When i have to achieve 100% code coverage for apex class which calls webservice i have to mock the callout and generate a fake response. The problem in this solution is that future methods has no return type and the test class that mocks the callout expects response.
Appreciate your responses.
Apex class:
global class Inventorycallout
{
@future(callout=true)
global static void inventorycall ()
{
Map<String, Object> m1 = new Map<String, Object>();
List<Product2> productlist = new List<Product2>();
Http http = new Http();
HttpRequest request = new HttpRequest();
String endpoint = 'https://th-superbadge-apex.herokuapp.com/equipment';
request.setMethod('GET');
request.setEndpoint(endpoint);
HttpResponse response = http.send(request);
system.debug(response.getBody());
List<Object> responselist = (List<Object>) JSON.deserializeUntyped(response.getBody());
for(Object o : responselist)
{
Product2 pr = new Product2();
m1 = (Map<String, Object>)o;
pr.Replacement_Part__c= (Boolean)m1.get('replacement');
pr.Current_Inventory__c = (Decimal)m1.get('quantity');
pr.Name= (string)m1.get('name');
pr.Maintenance_Cycle__c= (Decimal)m1.get('maintenanceperiod');
pr.Lifespan_Months__c= (Decimal)m1.get('lifespan');
pr.Warehouse_SKU__c= (string)m1.get('sku');
productlist.add(pr);
}
if(productlist.size() > 0)
{
Schema.SObjectField f = Product2.Fields.Warehouse_SKU__c;
Database.UpsertResult [] cr = Database.upsert(productlist,f,false);
}
Test class:
@isTest(seeallData = false)
private class inventorycallouttest
{
static testmethod void testrun()
{
Test.startTest();
setMock(HttpCalloutMock.class,new MockHttpcall());
HttpResponse response = Inventorycallout.inventorycall();
String contentType = response.getHeader('Content-Type');
System.assert(contentType == 'application/json');
String actualValue = response.getBody();
String expectedValue = '[{"fakeresponse":"test"},{"fakeresponse2":"test2"}]';
System.assertEquals(actualValue, expectedValue);
System.assertEquals(200, response.getStatusCode());
Test.stopTest();
}
}
apex class calls webservice to retrieve product information. I have to schedule this class to run at night 10 pm everyday and write test class for the callout.
Solution:
I have written apex class which does the callout and upsert product object. Since I have to schedule this update i called the apex class from schedule class. As I cannot do synchronous callouts in schedule apex i have made the method as asychronous(@future) (asynchronous methods has no return type). When i have to achieve 100% code coverage for apex class which calls webservice i have to mock the callout and generate a fake response. The problem in this solution is that future methods has no return type and the test class that mocks the callout expects response.
Appreciate your responses.
Apex class:
global class Inventorycallout
{
@future(callout=true)
global static void inventorycall ()
{
Map<String, Object> m1 = new Map<String, Object>();
List<Product2> productlist = new List<Product2>();
Http http = new Http();
HttpRequest request = new HttpRequest();
String endpoint = 'https://th-superbadge-apex.herokuapp.com/equipment';
request.setMethod('GET');
request.setEndpoint(endpoint);
HttpResponse response = http.send(request);
system.debug(response.getBody());
List<Object> responselist = (List<Object>) JSON.deserializeUntyped(response.getBody());
for(Object o : responselist)
{
Product2 pr = new Product2();
m1 = (Map<String, Object>)o;
pr.Replacement_Part__c= (Boolean)m1.get('replacement');
pr.Current_Inventory__c = (Decimal)m1.get('quantity');
pr.Name= (string)m1.get('name');
pr.Maintenance_Cycle__c= (Decimal)m1.get('maintenanceperiod');
pr.Lifespan_Months__c= (Decimal)m1.get('lifespan');
pr.Warehouse_SKU__c= (string)m1.get('sku');
productlist.add(pr);
}
if(productlist.size() > 0)
{
Schema.SObjectField f = Product2.Fields.Warehouse_SKU__c;
Database.UpsertResult [] cr = Database.upsert(productlist,f,false);
}
Test class:
@isTest(seeallData = false)
private class inventorycallouttest
{
static testmethod void testrun()
{
Test.startTest();
setMock(HttpCalloutMock.class,new MockHttpcall());
HttpResponse response = Inventorycallout.inventorycall();
String contentType = response.getHeader('Content-Type');
System.assert(contentType == 'application/json');
String actualValue = response.getBody();
String expectedValue = '[{"fakeresponse":"test"},{"fakeresponse2":"test2"}]';
System.assertEquals(actualValue, expectedValue);
System.assertEquals(200, response.getStatusCode());
Test.stopTest();
}
}