I'm trying to mock Database.BatchableContext to make my unit tests more robust and to eliminate excess usage of Test.isRunningTest() running in production code. Few hacks are available like Json.deserialize('{"jobId":""}', Database.BatchableContextImpl.class)
but feels bad.
My batch class implementation is boring and ordinary:
public class LongWalksOnTheBatch implements Database.Batchable {
public Iterable start(context) {...}
public void execute(context, scopes) {...}
public void finish(context) {...}
}
And most of the time, these techniques are sufficient:
Using Test.startTest() and Test.stopTest() to run 1 iteration:
//arrange Database.Batchable batch = new LongWalksOnTheBatch(); //act Test.startTest(); Database.executeBatch(batch, 1); Test.stopTest(); //assert System.assert(sideEffects);
Manually calling the execute() method to observe more complex behaviours:
//arrange Database.Batchable batch = new LongWalksOnTheBatch(); //act batch.execute(null, new List<SObject>()); batch.execute(null, new List<SObject>()); batch.execute(null, new List<SObject>()); //assert System.assert(sideEffects);
But this gets a bit crap when that Database.BatchableContext is actually needed. For example to abort the job. But trying to getJobId() will result in a big fat NullPointerException. So what to do?