You need to sign in to do that
Don't have an account?

Test Coverage Issue with Webservice Test Class
I have a Static Webservice Method defined in a Global class. That Webservice method has a string argument (Opportuinty ID) and It is retriving Oppotunity data withing the same method and send it out with Webservice callout and also I am doing some string manipulation and DML Operation in the same webserive method . I am Calling this class through Custom List View Button on Opportunity. It worked really well and does what I needed. But Now my biggest problem is how to test this webservice method or Global class using TestMethod.
1) I tried to do that and I got an Error "Methods defined as TestMethod do not support Web service callouts, test skipped"
2) I tried to create httpCallOutMock interface and It give me Error "System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out"
3) I tried to Put my DML execution before test.StartTest() then I put Test.Mock() to call webserive out and last Test.StopTest() but This did not work even. I don't know now what to do. I am going to paste my Webserive method and also test class to see if I could get any help from discussion board. Thanks Guys in advanced.
$$ APEX CLASS $$
global class sendToEncompass{
// @future(callout=true)
// public String EncompassMSG;
WebService static String basicCallout(String OppID){
opportunity opp = [select id, Loan_Number__c,Borrower_SSN__c, Co_Borrower_First_Name__c, Co_Borrower_Last_Name__c, Co_Borrower_SSN__c, Borrower_Email__c, Borrower_First_Name__c, Borrower_Last_Name__c, owner.email, Subject_Property_Street__c, Subject_Property_City__c, Subject_Property_Zip__c, Processing_Notes__c from Opportunity where id =:OppID];
HttpRequest req = new HttpRequest();
req.setClientCertificateName('xxx');
req.setEndpoint('https://api.xxx.yyy....');
req.setMethod('POST');
req.setHeader('Content-Type', 'application/xml');
req.setTimeout(120000);
req.setBody(
'<LoanEntries xmlns="xxx">' +
'<LoanData>' +
'<LoanField>' +
'<field_id>CX.SALESFORCELINKIDATE</field_id>' +
'<field_value>'+System.now().format('MM/dd/yyyy')+'</field_value>' +
'</LoanField>' +
'<LoanField>' +
'<field_id>LoanOfficer</field_id>' +
'<field_value>'+opp.owner.email+'</field_value>' +
'</LoanField>' +
'<LoanField>' +
'<field_id>36</field_id>' +
'<field_value>'+opp.Borrower_First_Name__c+'</field_value>' +
'</LoanField>' +
'<LoanField>' +
'<field_id>37</field_id>' +
'<field_value>'+opp.Borrower_Last_Name__c+'</field_value>' +
'</LoanField>' +
'<LoanField>' +
'<field_id>11</field_id>' +
'<field_value>'+opp.Subject_Property_Street__c+'</field_value>' +
'</LoanField>' +
'<LoanField>' +
'<field_id>12</field_id>' +
'<field_value>'+opp.Subject_Property_City__c+'</field_value>' +
'</LoanField>' +
'<LoanField>' +
'<field_id>15</field_id>' +
'<field_value>'+opp.Subject_Property_Zip__c+'</field_value>' +
'</LoanField>' +
'<LoanField>' +
'<field_id>364</field_id>' +
'<field_value>'+opp.Loan_Number__c+'</field_value>' +
'</LoanField>' +
'<LoanField>' +
'<field_id>65</field_id>' +
'<field_value>'+opp.Borrower_SSN__c+'</field_value>' +
'</LoanField>' +
'<LoanField>' +
'<field_id>68</field_id>' +
'<field_value>'+opp.Co_Borrower_First_Name__c+'</field_value>' +
'</LoanField>' +
'<LoanField>' +
'<field_id>69</field_id>' +
'<field_value>'+opp.Co_Borrower_Last_Name__c+'</field_value>' +
'</LoanField>' +
'<LoanField>' +
'<field_id>97</field_id>' +
'<field_value>'+opp.Co_Borrower_SSN__c+'</field_value>' +
'</LoanField>' +
'<LoanField>' +
'<field_id>1240</field_id>' +
'<field_value>'+opp.Borrower_Email__c+'</field_value>' +
'</LoanField>' +
'</LoanData>' +
'</LoanEntries>'
);
// req.setBody('{"CX.SALESFORCELINKIDATE":"'+System.now().format('MM/dd/yyyy')+'","LoanOfficer":"'+opp.owner.email+'", "36":"'+opp.Borrower_First_Name__c+'","37":"'+opp.Borrower_Last_Name__c+'","11":"'+opp.Subject_Property_Street__c+'","12":"'+opp.Subject_Property_City__c+'","15":"'+opp.Subject_Property_Zip__c+'","364":"'+Opp.Loan_Number__c+'","65":"'+Opp.Borrower_SSN__c+'","68":"'+opp.Co_Borrower_First_Name__c+'","69":"'+opp.Co_Borrower_Last_Name__c+'","97":"'+opp.Co_Borrower_SSN__c+'","1240":"'+opp.Borrower_Email__c+'"}');
//req.setEndpoint('https://xxxyyyy....xxxx');
//req.setMethod('GET');
Http http = new Http();
// try{
HTTPResponse res = http.send(req);
//return res.getBody();
// System.debug(res.getBody());
String loanID = res.getBody();
// return loanID;
system.debug('My Returned Body: '+loanID);
if(loanID.contains('Created')){
loanID = loanID.split(':', 14)[2];
loanID = (loanID.split('<',39)[0]).trim();
system.debug(loanID);
opp.GUID__c = loanID;
// EncompassMSG = 'Encompass loan record is successfully created, Click ok to continue';
}
else{
loanID = loanID.split(':', 14)[2];
loanID = (loanID.split('<',39)[0]).trim();
system.debug(loanID);
opp.GUID__c = 'Error: ' +loanID;
//EncompassMSG = 'Error is occured while creating Encompass record, please try again or contact support';
}
update opp;
if((opp.GUID__c).contains('Error')){
return 'Error is occured while creating Encompass record, please try again or contact support';
}else{
return 'Encompass loan record is successfully created';
}
// }
// catch(System.CalloutException e){
// return 'Request time is out, Please try again';
// }
}
}
$$ Test Class $$
@isTest
global class MockHttpEncompassResponseGenerator implements HttpCalloutMock {
// Implement this interface method
global HTTPResponse respond(HTTPRequest req) {
// Optionally, only send a mock response for a specific endpoint
// and method.
//sendToEncompass sE = new sendToEncompass();
// Create a fake response
HttpResponse res = new HttpResponse();
res.setHeader('Content-Type', 'application/Xml');
// res.setBody('{"CX.SALESFORCELINKIDATE":"'+System.now().format('MM/dd/yyyy')+'","LoanOfficer":"'+opp.owner.email+'", "36":"'+opp.Borrower_First_Name__c+'","37":"'+opp.Borrower_Last_Name__c+'","11":"'+opp.Subject_Property_Street__c+'","12":"'+opp.Subject_Property_City__c+'","15":"'+opp.Subject_Property_Zip__c+'","364":"'+Opp.Loan_Number__c+'","65":"'+Opp.Borrower_SSN__c+'","68":"'+opp.Co_Borrower_First_Name__c+'","69":"'+opp.Co_Borrower_Last_Name__c+'","97":"'+opp.Co_Borrower_SSN__c+'","1240":"'+opp.Borrower_Email__c+'","1222":"Loan Created:{8de3c840-cc26-4970-b10e-d441b090c50d}"}');
// res.setBody("":""'Loan Created :{8de3c840-cc26-4970-b10e-d441b090c50d}');
res.setBody('{"Loan Created : ":"Loan Created :{8de3c840-cc26-4970-b10e-d441b090c50d}"}');
System.debug('Body of webservice '+res.getBody());
// res.setStatusCode(200);
return res;
}
@isTest static void testCallout() {
Opportunity opp = new Opportunity(Name='demoTest',
CloseDate=date.newInstance(2014, 4, 30),
StageName='Active',
Loan_Number__c='123456789101112',
Borrower_SSN__c='8529518478',
Co_Borrower_First_Name__c='FirstTest',
Co_Borrower_Last_Name__c='LastTest',
Co_Borrower_SSN__c='8526547458',
Borrower_Email__c='demo@testemail.com',
Borrower_First_Name__c='borrowerFirstName',
Borrower_Last_Name__c='borrowerLastName',
Subject_Property_Street__c='123 Main St',
Subject_Property_City__c='Los Angeles',
Subject_Property_Zip__c='98103',
Processing_Notes__c='processingNotes');
Database.insert(opp);
sendToEncompass.basicCallout(opp.id);
// Set mock callout class
Test.StartTest();
Test.setMock(HttpCalloutMock.class, new MockHttpEncompassResponseGenerator());
// Call method to test.
// This causes a fake response to be sent
// from the class that implements HttpCalloutMock.
HttpRequest req = new HttpRequest();
req.setClientCertificateName('xxx');
req.setEndpoint('https://api.xxx/yyy');
req.setMethod('POST');
req.setTimeout(12000);
Http h = new Http();
HttpResponse res = h.send(req);
String loanID = res.getBody();
//System.debug('Response Body '+res.getBody());
Test.stopTest();
}
}
1) I tried to do that and I got an Error "Methods defined as TestMethod do not support Web service callouts, test skipped"
2) I tried to create httpCallOutMock interface and It give me Error "System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out"
3) I tried to Put my DML execution before test.StartTest() then I put Test.Mock() to call webserive out and last Test.StopTest() but This did not work even. I don't know now what to do. I am going to paste my Webserive method and also test class to see if I could get any help from discussion board. Thanks Guys in advanced.
$$ APEX CLASS $$
global class sendToEncompass{
// @future(callout=true)
// public String EncompassMSG;
WebService static String basicCallout(String OppID){
opportunity opp = [select id, Loan_Number__c,Borrower_SSN__c, Co_Borrower_First_Name__c, Co_Borrower_Last_Name__c, Co_Borrower_SSN__c, Borrower_Email__c, Borrower_First_Name__c, Borrower_Last_Name__c, owner.email, Subject_Property_Street__c, Subject_Property_City__c, Subject_Property_Zip__c, Processing_Notes__c from Opportunity where id =:OppID];
HttpRequest req = new HttpRequest();
req.setClientCertificateName('xxx');
req.setEndpoint('https://api.xxx.yyy....');
req.setMethod('POST');
req.setHeader('Content-Type', 'application/xml');
req.setTimeout(120000);
req.setBody(
'<LoanEntries xmlns="xxx">' +
'<LoanData>' +
'<LoanField>' +
'<field_id>CX.SALESFORCELINKIDATE</field_id>' +
'<field_value>'+System.now().format('MM/dd/yyyy')+'</field_value>' +
'</LoanField>' +
'<LoanField>' +
'<field_id>LoanOfficer</field_id>' +
'<field_value>'+opp.owner.email+'</field_value>' +
'</LoanField>' +
'<LoanField>' +
'<field_id>36</field_id>' +
'<field_value>'+opp.Borrower_First_Name__c+'</field_value>' +
'</LoanField>' +
'<LoanField>' +
'<field_id>37</field_id>' +
'<field_value>'+opp.Borrower_Last_Name__c+'</field_value>' +
'</LoanField>' +
'<LoanField>' +
'<field_id>11</field_id>' +
'<field_value>'+opp.Subject_Property_Street__c+'</field_value>' +
'</LoanField>' +
'<LoanField>' +
'<field_id>12</field_id>' +
'<field_value>'+opp.Subject_Property_City__c+'</field_value>' +
'</LoanField>' +
'<LoanField>' +
'<field_id>15</field_id>' +
'<field_value>'+opp.Subject_Property_Zip__c+'</field_value>' +
'</LoanField>' +
'<LoanField>' +
'<field_id>364</field_id>' +
'<field_value>'+opp.Loan_Number__c+'</field_value>' +
'</LoanField>' +
'<LoanField>' +
'<field_id>65</field_id>' +
'<field_value>'+opp.Borrower_SSN__c+'</field_value>' +
'</LoanField>' +
'<LoanField>' +
'<field_id>68</field_id>' +
'<field_value>'+opp.Co_Borrower_First_Name__c+'</field_value>' +
'</LoanField>' +
'<LoanField>' +
'<field_id>69</field_id>' +
'<field_value>'+opp.Co_Borrower_Last_Name__c+'</field_value>' +
'</LoanField>' +
'<LoanField>' +
'<field_id>97</field_id>' +
'<field_value>'+opp.Co_Borrower_SSN__c+'</field_value>' +
'</LoanField>' +
'<LoanField>' +
'<field_id>1240</field_id>' +
'<field_value>'+opp.Borrower_Email__c+'</field_value>' +
'</LoanField>' +
'</LoanData>' +
'</LoanEntries>'
);
// req.setBody('{"CX.SALESFORCELINKIDATE":"'+System.now().format('MM/dd/yyyy')+'","LoanOfficer":"'+opp.owner.email+'", "36":"'+opp.Borrower_First_Name__c+'","37":"'+opp.Borrower_Last_Name__c+'","11":"'+opp.Subject_Property_Street__c+'","12":"'+opp.Subject_Property_City__c+'","15":"'+opp.Subject_Property_Zip__c+'","364":"'+Opp.Loan_Number__c+'","65":"'+Opp.Borrower_SSN__c+'","68":"'+opp.Co_Borrower_First_Name__c+'","69":"'+opp.Co_Borrower_Last_Name__c+'","97":"'+opp.Co_Borrower_SSN__c+'","1240":"'+opp.Borrower_Email__c+'"}');
//req.setEndpoint('https://xxxyyyy....xxxx');
//req.setMethod('GET');
Http http = new Http();
// try{
HTTPResponse res = http.send(req);
//return res.getBody();
// System.debug(res.getBody());
String loanID = res.getBody();
// return loanID;
system.debug('My Returned Body: '+loanID);
if(loanID.contains('Created')){
loanID = loanID.split(':', 14)[2];
loanID = (loanID.split('<',39)[0]).trim();
system.debug(loanID);
opp.GUID__c = loanID;
// EncompassMSG = 'Encompass loan record is successfully created, Click ok to continue';
}
else{
loanID = loanID.split(':', 14)[2];
loanID = (loanID.split('<',39)[0]).trim();
system.debug(loanID);
opp.GUID__c = 'Error: ' +loanID;
//EncompassMSG = 'Error is occured while creating Encompass record, please try again or contact support';
}
update opp;
if((opp.GUID__c).contains('Error')){
return 'Error is occured while creating Encompass record, please try again or contact support';
}else{
return 'Encompass loan record is successfully created';
}
// }
// catch(System.CalloutException e){
// return 'Request time is out, Please try again';
// }
}
}
$$ Test Class $$
@isTest
global class MockHttpEncompassResponseGenerator implements HttpCalloutMock {
// Implement this interface method
global HTTPResponse respond(HTTPRequest req) {
// Optionally, only send a mock response for a specific endpoint
// and method.
//sendToEncompass sE = new sendToEncompass();
// Create a fake response
HttpResponse res = new HttpResponse();
res.setHeader('Content-Type', 'application/Xml');
// res.setBody('{"CX.SALESFORCELINKIDATE":"'+System.now().format('MM/dd/yyyy')+'","LoanOfficer":"'+opp.owner.email+'", "36":"'+opp.Borrower_First_Name__c+'","37":"'+opp.Borrower_Last_Name__c+'","11":"'+opp.Subject_Property_Street__c+'","12":"'+opp.Subject_Property_City__c+'","15":"'+opp.Subject_Property_Zip__c+'","364":"'+Opp.Loan_Number__c+'","65":"'+Opp.Borrower_SSN__c+'","68":"'+opp.Co_Borrower_First_Name__c+'","69":"'+opp.Co_Borrower_Last_Name__c+'","97":"'+opp.Co_Borrower_SSN__c+'","1240":"'+opp.Borrower_Email__c+'","1222":"Loan Created:{8de3c840-cc26-4970-b10e-d441b090c50d}"}');
// res.setBody("":""'Loan Created :{8de3c840-cc26-4970-b10e-d441b090c50d}');
res.setBody('{"Loan Created : ":"Loan Created :{8de3c840-cc26-4970-b10e-d441b090c50d}"}');
System.debug('Body of webservice '+res.getBody());
// res.setStatusCode(200);
return res;
}
@isTest static void testCallout() {
Opportunity opp = new Opportunity(Name='demoTest',
CloseDate=date.newInstance(2014, 4, 30),
StageName='Active',
Loan_Number__c='123456789101112',
Borrower_SSN__c='8529518478',
Co_Borrower_First_Name__c='FirstTest',
Co_Borrower_Last_Name__c='LastTest',
Co_Borrower_SSN__c='8526547458',
Borrower_Email__c='demo@testemail.com',
Borrower_First_Name__c='borrowerFirstName',
Borrower_Last_Name__c='borrowerLastName',
Subject_Property_Street__c='123 Main St',
Subject_Property_City__c='Los Angeles',
Subject_Property_Zip__c='98103',
Processing_Notes__c='processingNotes');
Database.insert(opp);
sendToEncompass.basicCallout(opp.id);
// Set mock callout class
Test.StartTest();
Test.setMock(HttpCalloutMock.class, new MockHttpEncompassResponseGenerator());
// Call method to test.
// This causes a fake response to be sent
// from the class that implements HttpCalloutMock.
HttpRequest req = new HttpRequest();
req.setClientCertificateName('xxx');
req.setEndpoint('https://api.xxx/yyy');
req.setMethod('POST');
req.setTimeout(12000);
Http h = new Http();
HttpResponse res = h.send(req);
String loanID = res.getBody();
//System.debug('Response Body '+res.getBody());
Test.stopTest();
}
}
Hi ,
The mail article: http://help.salesforce.com/apex/HTViewSolution?id=000003701&.
Also see the related threads,
The calls to DML operations must not be part of the Test.startTest/Test.stopTest block.
http://salesforce.stackexchange.com/questions/17293/system-calloutexception-you-have-uncommitted-work-pending-please-commit-or-rol
Here is the trick.
You have to make all the callouts before doing any DML.
So
This is Allowed : Callout --> DML
Not Allowed : DML --> Callout
Not Allowed : Callout --> DML ----> Callout
https://developer.salesforce.com/forums/ForumsMain?id=906F00000009AtjIAE
In that case you have to carry out the callout asynchronously - via an @future method is one way. Do you need to use the results of the callout in your VF page?
https://developer.salesforce.com/forums/ForumsMain?id=906F000000091cRIAQ
@future annotation was added to the applyURLString() method. For my specific case it has worked perfectly.
https://developer.salesforce.com/forums/ForumsMain?id=906F000000091DPIAY
This is an error due to a programming bug in the class. You can only make callouts when there are no pending database operations waiting.
https://success.salesforce.com/answers?id=90630000000hSThAAM
Regards,
Ashish
I am agree with Ashish_SFDC . We can not make call out after DML . Use Mock class feature provided by salesforce in Latest release .
So your test class will be as follows :
static testMethod void TestMethodTest() {
// TO DO: implement unit test
// Create the necessary data
Test.startTest();
Test.setMock(HttpCalloutMock.class , new MockHttpResponseGenerator()); // Create dummy response in MockHttpResponseGenerator Class
// Use classname.methodname if class is global class and method is webservice static
Test.stopTest();
}
Thanks ,
Ajay