5

我无法在线获得有关此问题的任何可靠信息。但我认为这一定是一个影响很多人的问题。

基本上我在沙箱中编写了一个简单的触发器和测试类,对其进行了测试,当它很好时,我将它部署到 PRD。

我先尝试了验证模式,我得到了这个错误。

System.LimitException:SOQL 查询过多:101

此错误显示在其他一些测试类中发生。所以我觉得我的触发器中的测试用例运行了,再加上剩余的测试用例不知何故超出了限制。

所以我们的单元测试中 SOQL 查询的总数必须少于 100。这有点难以接受吧?我可以想象有这么多的测试用例,我们肯定需要超过 100 个查询。

那么有什么方法可以避免达到这个限制,因为 Salesforce 甚至在部署单行代码时都会运行所有测试用例。

我没有任何常见的嫌疑人……比如 for 循环中的 SOQL。

更新:2012 年 8 月 19 日:我现在发布测试类和触发器的源代码

测试类:

@isTest

私有类 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 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.');
        }
    }   

}

你能分享你的想法吗?

谢谢,

卡尔文

4

2 回答 2

10

查看您的一些测试类会有所帮助,但需要注意的重要一点是您需要使用 Test.startTest() 和 Test.stopTest() 方法。这个想法是,您为设置测试所做的任何查询或 DML 操作都应该在 Test.startTest() 方法之前关闭。然后,在测试您的代码(例如执行一个方法)时,您要在 start 和 stop 方法调用之间进行测试。

这给出了单元测试上下文。这基本上会忽略在您的开始和停止测试之外完成的任何 dml 或查询,并且只计算在测试之间发生的事情。否则,所有设置代码和实际测试代码都被视为同一上下文的一部分,因此要计入限制。

这个链接应该对这个主题有更多的了解:http ://wiki.developerforce.com/page/An_Introduction_to_Apex_Code_Test_Methods

于 2012-08-17T18:54:13.163 回答
1

要记住的另一件事是您在 for 循环中执行的 SOQL。您可以在循环之前创建一个列表并存储查询结果。这样您就不会遇到调控器限制的问题,因为每个事务只使用一个 SOQL 语句。

于 2012-08-29T18:03:22.357 回答