5

この問題に関する信頼できる情報をオンラインで入手できませんでした。しかし、それは多くの人に影響を与えているに違いない問題だと思います。

基本的に、サンドボックスに簡単なトリガーとテスト クラスを作成してテストし、問題がなければ PRD にデプロイしました。

最初に検証モードを試したところ、このエラーが発生しました。

System.LimitException: SOQL クエリが多すぎます: 101

このエラーは、他のテスト クラスで発生することが示されました。そのため、トリガーのテスト ケースが実行され、これが残りのテスト ケースと相まって、何らかの形で制限を超えたように感じます。

したがって、単体テストの SOQL クエリの総数は 100 未満である必要があります。これは少し難しいですね。非常に多くのテスト ケースがあると想像できますが、100 以上のクエリが必要になることは間違いありません。

では、Salesforce は 1 行のコードをデプロイするだけでもすべてのテスト ケースを実行するため、この制限に達するのを回避するにはどうすればよいでしょうか。

通常の容疑者はいません... 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

いくつかのテスト クラスを確認することは役に立ちますが、注意すべき重要な点の 1 つは、Test.startTest() および Test.stopTest() メソッドを使用する必要があることです。テストをセットアップするために実行するクエリまたは DML 操作は、Test.startTest() メソッドの前に停止する必要があるという考え方です。次に、テストしているメソッドの実行などのコードをテストするときは、開始メソッド呼び出しと停止メソッド呼び出しの間にそれを行います。

これにより、単体テストのコンテキストが提供されます。これは基本的に、テストの開始と停止以外で行われた dml またはクエリを無視し、その間に発生したことのみをテストの一部としてカウントします。それ以外の場合、すべてのセットアップ コードと実際のテスト コードはすべて同じコンテキストの一部と見なされるため、制限にカウントされる可能性があります。

このリンクは、件名にいくつかの追加の光を当てる必要があります: http://wiki.developerforce.com/page/An_Introduction_to_Apex_Code_Test_Methods

于 2012-08-17T18:54:13.163 に答える
1

留意すべきもう 1 つの点は、for ループで実行する SOQL です。リストを作成し、ループの前にクエリの結果を保存できます。これにより、トランザクションごとに 1 つの SOQL ステートメントしか使用しないため、ガバナー制限の問題に直面することはありません。

于 2012-08-29T18:03:22.357 に答える