Salesforce: Avoiding governor limits in Test classes across the board
Asked Answered
S

2

6

I have not been able to get any reliable information about this issue online. But I think it must be an issue which must be affecting a lot of people.

Basically I wrote a simple trigger and test class in sandbox, tested it and when it was fine I deployed it to PRD.

I tried the validation mode first and I got this error.

System.LimitException: Too many SOQL queries: 101

This error was shown to occur in some other test class. So I feel that the test cases in my trigger ran and this coupled with the remaining test cases somehow overshot the limit.

So the total number of SOQL queries in our unit tests must be less than 100. This is a little hard to adere to right? I can imagine with so many test cases, surely we will need more than 100 queries.

So what are the ways to avoid hitting this limit because Salesforce runs all the test cases when deploying even a single line of code.

I dont not have any of the usual suspects...like SOQL within a for loop.

UPDATE: 8/19/2012: I am now posting the source code of the test class and trigger

Test Class:

@isTest

private class TestAccountDuplicateWebsiteTrigger {

static testMethod void myUnitTest() {
    try{
    // TO DO: implement unit test
    Test.startTest();
    Account a1;      
    a1 = new Account();
    a1.name = 'GMSTest';    
    a1.Website = 'www.test.com';            



    Account a2;      
    a2 = new Account();
    a2.name = 'GMSTest2';   
    a2.Website = 'www.test.com';            


    Account a3;      
    a3 = new Account();
    a3.name = 'GMSTest3';   
    a3.Website = 'www.test1.com';           


    insert a1;
    insert a2;
    //insert a3;
    Test.stopTest(); 


    }
    catch (Exception e)
    {
    }

}

}

Trigger

trigger osv_unique_website_for_account on Account (before insert, before update) {  

    //Map which has no duplicates with website as the key
    Map<String, Account> accountMap = new Map<String, Account>();

    for (Account account: System.Trigger.new)
    {
        //Ensure that during an update, if an website does not change - it should not be treated as a duplicate
        if ((account.Website != null) && (System.Trigger.isInsert ||            
            (account.Website != System.Trigger.oldMap.get(account.Id).Website))) 
            {
                //check for duplicates among the new accounts in case of a batch
                 if (accountMap.containsKey(account.Website)) 
                 {
                    account.Website.addError('Cannot save account. Website already exists.');
                 } 
                 else 
                 {
                    accountMap.put(account.Website, account);
                 }

            }       
    }

    //Now map containing new account websites has been created. 
    //Check them against the account websites that ALREADY EXIST in salesforce. If website exists, display error.
    for (Account account : [SELECT Website FROM Account WHERE Website IN :accountMap.KeySet()]) 
    {
        Account newAccount = accountMap.get(Account.Website);
        if (newAccount!=null)
        {
            newAccount.Website.addError('Cannot save account. Website already exists.');
        }
    }   

}

Can you please share your thoughts?

Thanks,

Calvin

Sandstone answered 17/8, 2012 at 16:34 Comment(2)
You get this error Message because One of your Test classes (not all of them!) exceeds the governor limit. In error message you can see The class name. Post The code of that class here so we can check it out.Torpedo
Actually the class being shown is a class which is in PRD and currently the test cases are working fine. As John answered below maybe it happened because I did not used the startTest() and stopTest() to enclose my code in the test class.Sandstone
B
10

It would help to see some of your test classes but one important thing to note is that you need to make use to Test.startTest() and Test.stopTest() methods. The idea is that any queries or DML operations that you do to setup your test should be down before the Test.startTest() method. Then when testing your code such as executing a method your are testing do that between the start and stop method calls.

This gives the unit test context. Which will basically ignore any dml or queries done outside of your start and stop testing and only count what happens in between as part of your test. Otherwise all setup code and actual test code are all considered part of the same context and thus subject to be counted towards the limits.

This link should shed some additional light on the subject: http://wiki.developerforce.com/page/An_Introduction_to_Apex_Code_Test_Methods

Bagwig answered 17/8, 2012 at 18:54 Comment(3)
Sure this is something that was just suggested to me a little while ago. I will add these two statements in my test class. Thanks.Sandstone
hey John, I added these statements to my test class and it did not help. I have now posted the test class and trigger's code in my original post above.Sandstone
Marking as answer. Using the force.com IDE I was able to figure out the problem in another class. I used the starttest and stoptest in appropriate place.Sandstone
K
1

Another thing to keep in mind is the SOQL that you are executing in your for loop. You can create a list and store the results of your query before your loop.. That way you won't face an issue with the governor limits because you are only using one SOQL statement per transaction.

Kachine answered 29/8, 2012 at 18:3 Comment(3)
Yup this is the first thing I check for before proceeding to look for any other errors in coding.Sandstone
Thanks Richards.. ! Can you check this question ? Thanks !! https://mcmap.net/q/1772255/-how-to-populate-lookup-field-when-creating-a-new-custom-object-in-sfdc/1633936Kachine
I have replied...let me know if u need any more help there.Sandstone

© 2022 - 2024 — McMap. All rights reserved.