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
ppiyushppiyush 

System Assert fails on Production but successful in Sandbox

Hi there,

 

I have a Batch Apex class that I am trying to test, and for some reason, the test is successful in the Sandbox - when I run it from the IDE, but unsuccessful during deployment.

 

Code is below - any clues would be highly appreciated!

 

 

global class OpenProjectsCount implements Database.Batchable<sObject>{
	
	String query;
	
	global OpenProjectsCount(){
		query = 'SELECT id, Open_Projects__c FROM Contact';
	}
	
	global Database.QueryLocator start(Database.BatchableContext BC){
	
	   return Database.getQueryLocator(query);
	}
	
	global void execute(Database.BatchableContext BC, List<Contact> scope){
		for(Contact c:scope){
			c.Open_Projects__c = [select Count() from Opportunity where Related_Contact__c =: c.id and StageName!='Lost' and StageName!='Finished' and StageName!='Cancelled'];
		}
		update scope; 
	}
	
	global void finish(Database.BatchableContext BC){

	}

}

 

 

and the test class is:

 

 

@isTest
private class TestOpenProjects {

    static testMethod void myUnitTest() {
        Contact c = new Contact(LastName='TestContact');
        insert c;
        
        List <Opportunity> opp = new List<Opportunity>();
        
        for(integer i=0; i<200; i++){
        	Opportunity o = new Opportunity(Name='Test Project'+i, Related_Contact__c=c.id, StageName='Discussions', CloseDate=date.today());
        	opp.add(o);
        }
        insert opp;
        
        Test.StartTest();
        OpenProjectsCount ops = new OpenProjectsCount();
        ID batchprocessid = Database.executebatch(ops);
        Test.StopTest();
        
        List<Contact> con = [SELECT Open_Projects__c FROM Contact WHERE id=:c.id];
        System.assertEquals(con[0].Open_Project__c, 200);
    }
}

 

 

Of course, if I remove the System Assert, at least I dont fail the test, and I am able to deploy the class, but this is still an area of concern to me. Any pointers would be extremely helpful!

 

thanks,

Pranav

 

Best Answer chosen by Admin (Salesforce Developers) 
BritishBoyinDCBritishBoyinDC

Ah, a batch test can only run once - which means you can only pass 200 records into the test...

 

That's why the examples set the query, rather than have it as part of the constructor - look at the re-assign user example:

http://www.salesforce.com/us/developer/docs/apexcode/index.htm

 

See how there is a variable called query on the Batch Object that is set after they create the reassign object? When you run the test for that batch, you can then set the SOQL to include  'order by createddate desc limit 200'  - that way, the batch will only have to execute once, and should execute for the test records you created.

All Answers

BritishBoyinDCBritishBoyinDC

My guess is that the test isn't using the contact you're creating in the test script...

 

 

query = 'SELECT id, Open_Projects__c FROM Contact';

Since this isn't filtered, the single test iteration probably never processes your test contact in live, but if you have less than 200 in the Sandbox, it always does

 

Try adding a 'Order by CreatedDate desc' to the SOQL - it won't affect the execution, but that way, your new contact should always in included in the test iteration

 

ppiyushppiyush

Thanks for your suggestion - I tried your recommendation, but that doesnt seem to solve the problem. Again, the test system works fine, but when I try to deploy it, the System Assert fails again!

 

I did a little bit of digging, and found an exception in the log:

 

System.UnexpectedException: No more than one executeBatch can be called from within a testmethod.  Please make sure the iterable returned from your start method matches the batch size, resulting in one executeBatch invocation.

 

I am not sure what this really means.. any clues?

BritishBoyinDCBritishBoyinDC

Ah, a batch test can only run once - which means you can only pass 200 records into the test...

 

That's why the examples set the query, rather than have it as part of the constructor - look at the re-assign user example:

http://www.salesforce.com/us/developer/docs/apexcode/index.htm

 

See how there is a variable called query on the Batch Object that is set after they create the reassign object? When you run the test for that batch, you can then set the SOQL to include  'order by createddate desc limit 200'  - that way, the batch will only have to execute once, and should execute for the test records you created.

This was selected as the best answer
salesforce expertsalesforce expert

maan! excellent solution! you saved my life. thanks

satishkrsatishkr

What is the reason that it worked in Test sandbox and not in Production. I tried to recreate the exception in Test Sandbox by inserting more than 200 records and invoked the executeBatch() method with scope value as less as 50 but still I didn't receive the same UnExpectedException.