1

I am attempting to deploy an Apex Class from a sandbox environment to a production environment of Salesforce and I am having issues with the deployment. I am very new at this, so please forgive my ignorance in apex coding.

Here is the portion of the apex class that is causing the deployment to fail due to not meeting the minimum code coverage requirement. The error message is telling me that the 3rd line of the code below is where the error is coming from.

static testMethod void getCasesTest() {
    for (Case obj : [select Id from Case]) {
        delete obj;
    }

    System.runAs(createUser('test4356')){
      String queueName = 'TestQueue1';
      Group queue = new Group(Type='Queue', Name=queueName);
      insert queue;
      QueueSobject sobj = new QueueSobject(QueueId = queue.Id, SobjectType = 'Case');
      insert sobj;
        Case case1 = new Case(Subject='TestCase1', OwnerId = queue.Id, V1Association__c = true);
        Case case2 = new Case(Subject='TestCase2', OwnerId = queue.Id, V1Association__c = true);
        Case case3 = new Case(Subject='TestCase3', OwnerId = queue.Id, V1Association__c = true);
        Case case4 = new Case(Subject='TestCase4', V1Association__c = true);
        insert new Case[] {case1, case2, case3, case4};

        Case[] cases = V1CaseCollector.getCases(queue.Id, false);
        System.assertEquals(3, cases.size(), 'Incorrect numbers of cases.');

        case2.status = 'Closed';
        case3.V1Association__c = false;
        update new Case[] {case2, case3};
        Case[] newCases = V1CaseCollector.getCases(queue.Id, true);
        System.assertEquals(1, newCases.size(), 'Incorrect numbers of cases. One cases have to be closed');
        assertContains(case2, newCases, 'Incorrect data in result.');
        newCases = V1CaseCollector.getCases(queue.Id, false);
        System.assertEquals(1, newCases.size(), 'Incorrect numbers of cases. Two classes have to be not closed');
        assertContains(case1, newCases, 'Incorrect data in result.');
        newCases = V1CaseCollector.getCases(null, false);
        System.assertEquals(2, newCases.size(), 'Incorrect numbers of cases.');
    }
}

When I try to deploy the new Apex Class change set, I am getting the following error on this other test class:

API Name = V1CaseCollectorTestSuite.getCasesTest()
Type = Class
Line = 248
Column = 1
Problem = Failure Message: "System.Exception: Too many DML statements: 151", Failure Stack Trace: "Class.V1CaseCollectorTestSuite.getCasesTest: line 248, column 1"

Any ideas as to why I might be getting this error, and how I can go about correcting it so that I can correctly deploy my original change set?

3
  • 1
    What apex API version are you using? It looks like you're deleting all cases in the system as part of the test case (because it looks like "delete obj;" is failing), that's absolutely not something you can do since it'll will inevitably fail once you have too many cases in the system. Use tests with @isTest(seeAllData=false) annotations whenever possible, this is possible for API v24 and later. Using this annotation, you don't have to delete anything, tests won't see your production data. Commented Dec 21, 2012 at 9:31
  • 1
    The correct solution as noted below is to not to perform the delete operation within a loop of individual records, instead delete a list of records. The reason this is happening when you deploy this code into production is because there are more than 150 Case records in the production org which are being retrieved by your SELECT statement. You are then running into the 150 DML Statements limit while iterating and on the 151st delete, the exception is thrown.
    – Mark Pond
    Commented Dec 21, 2012 at 19:46
  • @MartinPeters - Your suggestion fixed my issue. Thanks for the help!
    – Brandon
    Commented Apr 1, 2013 at 15:49

2 Answers 2

2

Don't ever do DML or SOQL within an iteration scope. You can directly perform these on a collection object.

List<Case> lstToDelete = new List<Case>(); //COLLECTION
for (Case obj : [select Id from Case]) {
        //any possible business logic

        //collect objects you wish to delete/update/anything
        lstToDelete.add( obj); //COLLECT

        //never do another soql query for related records in an interation either, collect the id's in a collection object, and then query  as SELECT  fields FROM obj WHERE field IN:collection
    }

delete lstToDelete;  //BULK EXECUTE

In all honesty, if this is your testcode, I'm a bit worried about your production code. Topics as bulkifying code and governer limits are essential to know when coding on the force.com platform.

3
  • why are we even looping?makes no sense ! Commented Dec 20, 2012 at 20:29
  • I'm aware it doesn't in this case, but I wanted to display a more general practise, i'll update my example. Commented Dec 20, 2012 at 20:30
  • Thanks so much for the help on this, I'll try your solutions and respond back with the results. This code actually came from a class that was added when I installed the "Case Age in Business Hours" app, it was not something that I coded myself. I'm still very new to Apex coding, but I figured this wasn't coded very well due to my issues I'm having with it.
    – Brandon
    Commented Jan 8, 2013 at 16:12
0
static testMethod void getCasesTest() {
for (Case obj : [select Id from Case]) {
    delete obj;
}

Looking at above code there is a DML inside for loop.Never do this please .

static testMethod void getCasesTest() {
List<Case> lstcase=[Select Id from case];
delete lstcase;
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .