Below class gives error "You have uncommitted work pending. Please commit or rollback after calling out".
//Call out from batch
public void execute(Database.BatchableContext bc, List<Opportunity> scope) {
for(Opportunity o : scope){
Http http = new Http();
HttpRequest req = new HttpRequest();
HttpResponse res = new HttpResponse();
req.setEndpoint('https://posttestserver.com/post.php/?dump&dir=sandbox&' +o.name);
req.setHeader('Content-Type','x-www-form-urlencoded');
req.setHeader('Content-Length', '0');
system.debug('here5');
req.setMethod('GET');
req.setTimeOut(1200);
res = http.send(req);
String str = res.toString();
}
//Test Method
@isTest
static void testRecordUpdate(){
User u = createTestUser('System Administrator', 'Test', 'User');
List<Opportunity> opp = createOppRecord('Open', 1, u);
for(Opportunity o : opp){
o.stageName = 'Closed Won';
}
Test.setMock(HttpCalloutMock.class, new CalloutMock());
update opp; // this update makes callout
}
Trying to : When agent updates an opportunity, a callout is made and if response is successful, a record should be created in child object
Thanks.
Best Answer
A quick search may have found the answer, but it is really simple:
Wrap the mock in a test.startTest();
the reason is just like in a non-test environment. You cannot make a callout after doing any dml. Since you are creating a User, you cannot do a callout after in the same transaction. the test.StartTest() provides a new context for the callout to be run in as well as a new set of governor limits....
NOTE
Not sure why you have a batch code there, but if you are executing a batch from a trigger (potentially a problem) you will have to:
Call the start, execute, finish methods separately as it is a know issues that you will get this error regardless of the test.startTest if the callout is from a batch
If that is the case, unfortunatly you will have to wrap that part of your trigger that calls the batch in a :
and change your test method to:
You can also just wrap the callout in the batch to prevent it from running during a test except when a static property is set. that way your trigger is unaltered and the batch / test controls when the callout is made during a test method
i.e in the batch.
then set the
testCallout = true
from your test classthis leaves your trigger unaltered
You can find many topics on this issue by searching for "You have uncommitted work pending batch test" on this site