You need to sign in to do that
Don't have an account?
ppiyush
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
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
My guess is that the test isn't using the contact you're creating in the test script...
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
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?
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.
maan! excellent solution! you saved my life. thanks
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.