0

I write a test class for a batch that make a callout. So I wrote test class with a mock that I call in my batch test class. Here is the test class :

@isTest private class y_batch_Test {
    @isTest static void batchTest(){
        String query = 'SELECT Id FROM Mission__c';

        Contact c = new Contact(LastName = 'Test', Email = 'mail@mail.com');
        insert c;

        Mission__c[] missionsList = new List<Mission__c>();
        for (Integer i = 0; i < 10; i++) {
            Mission__c m = new Mission__c(Name = 'Mission class test ' + i,
                                          Description__c = 'test');
            missionsList.add(m);
        }
        insert missionsList;

        Test.startTest();
        Test.setMock(HttpCalloutMock.class, new y_batch_Mock());
        y_batch y = new y_batch();
        Database.executeBatch(y);
        Test.stopTest();

    }
}

And the mock class :

@isTest
public class y_batch_Mock implements HttpCalloutMock {
    public HTTPResponse respond(HTTPRequest req) {

        // Create a fake response
        HttpResponse res = new HttpResponse();

        res.setHeader('Content-Type', 'application/json'); 
        res.setBody('{"body":"test","group_id":"1234"}');

        return res;
    }
}

When I run the test class I got this error :

System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out

However I got 76% of code coverage... But the test class can't pass.

EDIT - change in the batch test class I try to use the method in this post here but it throw me the same exception. Here is the batch test class after the modifications :

@isTest private class y_batch_Test {
@isTest static void batchTest(){
    String query = 'SELECT Id FROM Mission__c';

    Contact c = new Contact(LastName = 'Test', Email = 'mail@mail.com');
    insert c;

    Mission__c[] missionsList = new List<Mission__c>();
    for (Integer i = 0; i < 10; i++) {
        Mission__c m = new Mission__c(Name = 'Mission class test ' + i,
                                      Description__c = 'test');
        missionsList.add(m);
    }
    insert missionsList;

    Database.BatchableContext bc;
    y_batch mbc = new y_batch ();
    Database.QueryLocatorIterator iter = mbc.start(bc).iterator();
    List<Mission__c> batch = new List<Mission__c>();
    Integer batchsize = 10;
    while (batchsize-- > 0 && iter.hasNext())
    {
        batch.add( (Mission__c) iter.next());
    }

    Test.startTest();
    Test.setMock( HttpCalloutMock.class, new y_batch_Mock());
    mbc.execute( bc, batch);
    mbc.finish( bc);
    Test.stopTest();

}
}

But maybe my error comes from my mock class ?

  • Do you receive any errors when running this batch outside of the test context? – Oles Malkov Sep 28 '16 at 16:46
  • 1
  • @cropredy I try to change the test class with the given exampe but I get the same error. I updated my post – dou Sep 29 '16 at 7:48
  • dou -- you blindly copied a little too freely - in my example, the callout was done in the start() method. I suspect your callout is done in the execute(). So, testing the start() method simply means invoking it and verifying that it returns a querylocator. Testing execute() - just pass in a list of Mission__c - these can be mocked without having to insert them. It is not clear why you need a Contact. – cropredy Sep 29 '16 at 23:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.