You need to sign in to do that
Don't have an account?
Bill5
Variables not set within a batch job when testing
When setting a instance variables value from within a batch context the value is not retained when testing.
Example code:
public class FinishLogic { public Integer val { get; set; } }
global class UserBatch implements Database.Batchable<sObject>, Database.Stateful { private final FinishLogic fl; public UserBatch(FinishLogic fl) { this.fl = fl; } global Iterable<sObject> start(Database.BatchableContext bc) { return [SELECT Id FROM User LIMIT 1]; } global void execute(Database.BatchableContext bc, List<User> scope) { //do some stuff } global void finish(Database.BatchableContext bc) { fl.val = 5; } }
@isTest public class TestUserBatch { static testMethod void shouldReturnFive() { final FinishLogic fl = new FinishLogic(); final UserBatch ub = new UserBatch(fl); Test.StartTest(); Database.executeBatch(ub); Test.StopTest(); System.assertEquals(5, fl.val); } }
The test should pass as the value should be 5 but instead returns null. This is a simple example for demonstration purposes, but this behavor is important to test the correct functionality of a batch.
If I add the line "System.assert(false, 'executing finish);" to the batches finish method the test does correctly fail with the error, therefore the method is being called. Does anybody know why this wouldn't work, or is this a known bug?
Thanks
Bill:
Is the problem the 'final' modifier on FinishLogic? From the SFDC doc:
The FinishLogic var isn't final only the reference to the FinishLogic instance, this is the correct implementation.
Bill -- Hmm, I've never done this.
* I've used Stateful variables within Batchable classes to pass information between multiiple execute() invocations and the finish() invocation (such as to write a log).
* I've communicated back to the caller of the batch only by updating SObjects in the Database within an execute() method (this is relevant only for testmethods)
Because batch APEX executes in a different context than the method that executes the batch, that SFDC can't pass variables between these two contexts -- In normal (non testmethod) usecases, some method does Database.executeBatch() and immediately gets a return - it doesn't wait around for the batch to finish. So the batch finish() doesn't have a way to tell the caller anything about its 'conclusion'. Thus testmethods have to adhere to this behavior.
See AsyncApexJob for what you can monitor about a batch job -- and it isn't much
I'm having the same problem. Have you resolved your issue?
My issue is documented here, and I believe it is exactly what you're describing:
http://boards.developerforce.com/t5/Apex-Code-Development/Unable-To-access-Variable-values-from-Execute-method-of-batch/m-p/672917#M125086
Thanks
King