function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Caleb_SidelCaleb_Sidel 

Testing @future fails if you clear the input list?

Has anyone else experienced issues when testing @future where if the method calling @future clears the input list then all of your test methods fail because the @future method thinks it has recieved a null list? See the code below. Thoughts: bug or feature?

 

There is a work around: do not use .clear() but instead re-create the list (i.e. move the list  

subsetAccountIds inside of the While loop below).

 

So next question - what is better for memory? clear an array or "re-create" the array? I would think clear() is more explicit and would free up the memory "immediately" whereas overwriting the array would be subject to gargage collection to dump the memory.

 

Thanks,

Caleb 

 

 

public without sharing class CustomerProductHandler {

 

//Takes the list of Accounts and breaks it into 10 equal parts

 public static void deleteCustomerProducts(List<Id> forAccountIds) {System.debug('BEGIN: CustomerProductHandler: deleteCustomerProducts(List<Id> forAccountIds)');

 

Integer smallerLooops = Math.mod(forAccountIds.size(),10);

List<Id> subsetAccountIds = new List<Id>();System.debug('smallerLooops = ' + smallerLooops);

 

while(!forAccountIds.isEmpty()) {System.debug(

'forAccountIds.size() = ' + forAccountIds.size());

 

for(Integer i=0; i < smallerLooops; i++) {

Id acctId = forAccountIds.remove(i);

subsetAccountIds.add(acctId);

}

 

System.debug('subsetAccountIds.size() = ' + subsetAccountIds.size());

 

if(!subsetAccountIds.isEmpty()) {

deleteCustomerProducts_AT_FUTURE(subsetAccountIds);

//IF I UNCOMMENT THIS LINE OF CODE BELOW the test method fails and my debug statements indicate that the size of the list passed to my @future method below is 0. However if I comment this out (as is done here) then the test methods work just fine.

//The problem is, I want to call @futurre with this array, then clear it, then call @future again. 

//subsetAccountIds.clear();

}

}

}

 

//Deletes all customer products related to the AccountIds

@future

 public static void deleteCustomerProducts_AT_FUTURE(List<Id> forAccountIds) {System.debug('BEGIN: CustomerProductHandler: deleteCustomerProducts_AT_FUTURE(List<Id> forAccountIds)');

 

EmailUtils eutils = new EmailUtils();

 

for(List<Customer_Product__c> custProducts : [SELECT Id

FROM Customer_Product__c

 WHERE Account__c IN :forAccountIds]) {

 

if(Limits.getDmlStatements() + 1 > Limits.getLimitDmlStatements()) {

emailError(eutils, forAccountIds,'Exceeded DML Statements.');}

else {

try {System.debug(

'deleting products: ' + custProducts);

delete custProducts;System.debug(

'products deleted');} catch(Exception exp) {

emailError(eutils, forAccountIds,exp.getMessage());

}

}

}

}

 

public static void emailError(EmailUtils eutils, List<Id> objectIds, String errorMsg) {System.debug('errorMsg = ' + errorMsg);

 

String objIds = ' ';

for(Id objId : objectIds){objIds += 'https://na3.salesforce.com/' + objId + '/n';

}

eutils.sendTextErrorEmailToAdmins('ERROR: CustomerProductHandler: deleteCustomerProducts', errorMsg + '/n /n Please review each of these accounts and manually review and possibly delete their Customer Products. Accounts: ' + objIds);

}

 

static testMethod void test_processAccounts() {

Account a = new Account();a.

Name = 'test';

a.Netsuite_Internal_ID__c = '999';

insert a;

 

Customer_Product__c cp = new Customer_Product__c();

cp.Name = 'test';cp.Customer_Product_ID__c =

'test';

cp.Account__c = a.Id;

insert cp;

 

Feature__c f = new Feature__c();

f.Name = 'test';

insert f;

 

Customer_Product_Feature__c cpf = new Customer_Product_Feature__c();

cpf.Name = 'Test' + cp.Id;cpf.Customer_Feature_ID__c =

'test';

cpf.Customer_Product__c = cp.Id;cpf.

Feature__c = f.Id; insert cpf;

 

Integer cpCount = [SELECT count() FROM Customer_Product__c WHERE Account__c =: a.Id];

System.assertEquals(1,cpCount);

 

Integer cpfCount = [SELECT count() FROM Customer_Product_Feature__c WHERE Feature__c =: f.Id];

System.assertEquals(1,cpfCount);

 

a.Netsuite_Internal_ID__c = '123';

Test.startTest();

update a;

Test.stopTest();

 

cpCount = [SELECT count() FROM Customer_Product__c WHERE Account__c =: a.Id];

System.assertEquals(0,cpCount);

 

//cpfCount = [SELECT count() FROM Customer_Product_Feature__c WHERE Feature__c =: f.Id];

//System.assertEquals(0,cpfCount);

 

}

 

}