I'm trying to write test code for a
Batchable class that
AllowsCallouts. I've written a lot of other test code that uses
HttpCalloutMock classes, and planned to do so for this class as well.
And, per best practices, I'm setting up my test data before calling
Test.startTest(). Even so, I get a CalloutException:
System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out
This somewhat makes sense, because my
start() method passes a SOQL query to
Database.getQueryLocator() and my
execute() method makes the web callouts. I'm guessing that when my test method calls
execute() run in the same context. In regular batch operation, they happen in separate contexts so there isn't any uncommitted work.
I intend to work around this by calling the methods directly, possibly even calling
Test.startTest(), and then using the returned
Database.QueryLocator to get the list of records I'll pass into
I don't like the fact that I'm not testing the batch size used by the static method that kicks off the batch with
Database.executeBatch(), so I'll probably have that use a constant that I can reference from my test code to ensure it's using the same batch size.
Salesforce kind of addresses this in the "Asynchronous Apex and Mock Callouts" section of the Summer '13 Release Notes, but they don't make reference to Batchable classes with Callouts. They only talk about making callouts and testing Batchable classes in the same test method.
So, my question is whether there is a better way to write this test. I'm also throwing this out so others searching the site can learn about possible workarounds.