+ Start a Discussion
John AthitakisJohn Athitakis 

Test Code for REST Service?

So I worked out some code to invoke a rest service off of an event in SFDC. I wrote the code out in two parts, the trigger and a @Future Class. I'm scratching my had as to where to begin however with the test classes (What I've been trying out seems to not be working, much of the documentation suggests test methods which don't seem supported any longer).


The trigger
trigger ProductLicenseRestCall on ProductLicense__c (before update) {
    for (ProductLicense__c a : Trigger.new) {
        ProductLicense__c b=Trigger.oldMap.get(a.ID);
        // make the asynchronous web service callout
        if(a.License_Sent__c != b.License_Sent__c){
		if(a.License_Sent__c==TRUE){
        a.Requested_Date_Time__c=DateTime.now();
        WebServiceCallout.sendNotification(String.valueOf(a.Id));    
        }}
    }

}

And the class. Its very simple and minimal and in all my testing in our sandbox, is working just fine. 
public class WebServiceCallout {

    @future (callout=true)
    public static void sendNotification(String licenseId) {
        
     list<productkeylicense__c> Pass = [SELECT Key__c FROM ProductKeyLicense__c ORDER BY  CreatedDate LIMIT 1];
        HttpRequest req = new HttpRequest();
        HttpResponse res = new HttpResponse();
        Http http = new Http();
        req.setEndpoint('https://acmecorp.com/endpoint/'+ licenseId);
        req.setMethod('POST');
        
        req.setHeader('License-Client-Key', Pass[0].Key__c);     

        try {
            res = http.send(req);
        } catch(System.CalloutException e) {
            System.debug('Callout error: '+ e);
            System.debug(res.toString());
        }

    }



}

 
Best Answer chosen by John Athitakis
Varun PareekVarun Pareek
John,

Since you are making an call out from the trigger which actually calls your future method, you should start at the trigger. This means that you would have to UPDATE a ProductLicense__c record which in turn would fire your trigger. Once the if condition (License_Sent__c) is met, it wil then fire trigger the future method. Also make sure that you implement the HTTPMock in the test class for which the documentation can be found here: https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_classes_restful_http_testing_httpcalloutmock.htm

Let me know if this helps.

Regards,
Varun.

All Answers

Varun PareekVarun Pareek
John,

Since you are making an call out from the trigger which actually calls your future method, you should start at the trigger. This means that you would have to UPDATE a ProductLicense__c record which in turn would fire your trigger. Once the if condition (License_Sent__c) is met, it wil then fire trigger the future method. Also make sure that you implement the HTTPMock in the test class for which the documentation can be found here: https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_classes_restful_http_testing_httpcalloutmock.htm

Let me know if this helps.

Regards,
Varun.
This was selected as the best answer
John AthitakisJohn Athitakis

So doing the first test class on the trigger gets me 100% coverage but I get a failure and I'm unsure how to fix this...I think it relates to what you linked above but unsure how to resolve this within the same test case cod:

 

@istest(SeeAllData=true)  //needed to insert SeeAllData since the code this triggers has a custom setting
public class TestLicenseService {
    static testMethod void validateLicenseTrigger() {
ProductLicense__c b = new ProductLicense__c();
b.License_Sent__c = FALSE;
        test.startTest();
insert b;
checkRecursive.resetRunOnceFlag();
b.License_Sent__c=TRUE;
update b;

system.assertEquals(b.License_Sent__c, True);       
test.stopTest();  
        }
}

Error:Methods defined as TestMethod do not support Web service callouts, test skipped

My confusion here is how to tie what you linked me to the class above (again this is just testing the TRIGGER that initiates the class?).

Can you give an example? For some reason this is quite vexxing :( 

Varun PareekVarun Pareek
There are two ways of handling web serivce call outs from test methods:
1. Skip the actual callout using If-else condition and using Test.isRunningTest() 
2. Use the Test.setMock() in your test class which would simulate the response from the web service (The hyperlink that I shared in my previous response)

For #1, your code would be like:
try {
	if(!Test.isRunningTest()){
		res = http.send(req);
	}
	else {
		//Assign dummy response here
		res = 'Dummy response per your web service';
	}
}
catch(Exception e){
	//... code here
}
For #2, follow this link: 
https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_classes_restful_http_testing_httpcalloutmock.htm
and use Test.setMock();