need help. I`m trying to write a test class for Batch apex however its failing. For some reason, I cant pass/save query to the test class. I need to pass a query to the test class so that batch class can execute.

To execute Batch class from Execute Anonymous window, I use below code however I`m not able to replicate this in a test class. I keep getting error "Final member variables can only be assigned in their declaration statement or inside a constructor". Can Someone please help?


Test Class:

public class SummarizeAccountTotal _Test {
     @isTest static void sumtotal() {

         Account Acc = New Account (Name='Acc test');
         Insert Acc;

         Date startdate = Date.newInstance(2016,11,10) ;
        Opportunity Opp = New Opportunity (Name='Sample Opp', start_date__c = startdate, CloseDate = startdate, stagename = 'prospecting', Amount=5000 );

        insert Opp ;


 //Execute Code for Batch Apex 
SummarizeAccountTotal sat = new SummarizeAccountTotal ();

// this line does not work and causes error
sat.query = 'Select Id, AccountId, Amount from Opportunity where AccountId != null and Amount > 0'; 




Batch Class:

    global class SummarizeAccountTotal implements Database.Batchable<sObject>, Database.Stateful{

   global final String query;
   global Map<Id, Account> accountmap;

   global SummarizeAccountTotal(){
   accountmap = new Map<Id, Account> ();

   global Database.QueryLocator start(Database.BatchableContext BC){
      return Database.getQueryLocator(query);

   global void execute(Database.BatchableContext BC, List<sObject> scope){

   List<Opportunity> ops = (List<Opportunity>)scope;

   for (Opportunity o : ops) {

   if (accountmap.containskey(o.AccountId)) {
   Account a = accountmap.get(o.AccountId);
   a.Test_Amount__c += o.Amount;
   accountmap.put(o.AccountId, a);
   accountmap.put(o.AccountId, new Account (Id = o.AccountId, Test_Amount__c = o.Amount));


global void finish(Database.BatchableContext BC){

   try {
   update accountmap.values();
   catch (Exception Ex) {

  • Just make property query not final (remove that word). OR better is to make constructor parameter and assign query there – kurunve Dec 13 '16 at 10:13

You cannot assign final variables directly and could only be assigned where you declare them or in constructor(which's written in your error message). Pretty strange that it worked with Execute Anonymous.

The best way to avoid the error is to put the query into constructor:

String query;
global SummarizeAccountTotal(){
   accountmap = new Map<Id, Account> ();
   query = 'Select Id, AccountId, Amount from Opportunity where AccountId != null and Amount > 0';

This approach allows you to be 100% sure that your batch will receive Opportunities and not i.e. accounts, and also let you not to remember about always filling the query variable when you want to use batch.


Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.