3

here's a brief rundown of the trigger I'm trying to test:

  • this trigger is trying to put a cap on records with a certain lead source. If someone selects this source and tries to save the record, it generates an error and tells them that they've hit the cap.
  • the trigger works in the sandbox as advertised

So here's the code for the trigger:

trigger ProtectedCap on Lead (before update) {
 List<Lead> protectedTotal = [SELECT Owner_ID__c FROM Lead WHERE Status = 'Protected'];
    for (Lead myLead : Trigger.new) {
        if (myLead.Status == 'Protected' && protectedTotal.size() >= 100) {
                String protectedError = 'Protected Leads are at 100, please remove leads from Protected status to add.';
                myLead.addError (protectedError);
                }
            }
        }

For the test class, I generated leads and assigned the lead status that I'm trying to cap. It runs and hits the error when it's supposed to, but of course the test thinks it's a bad error and fails out. To be honest there's probably a number of other things wrong with it but I don't know enough to know enough. Ya know?

Here's the test class:

@isTest
private class testNewLeadCap {
    static testMethod void validateNewLeadCap()
    {
        List<Lead> leads = new List<Lead>{};
        for(Integer i = 0; i <200; i++){
            Lead a = new Lead(FirstName = 'Test' + i, LastName = 'Testies' + i, Status = 'Protected');
            leads.add(a);
            }   
        test.startTest();
        insert leads;
        test.stopTest();    
}
}

Any assistance/insight would be greatly appreciated!

Cheers!

2 Answers 2

3

Your trigger logic looks like it may not be correct in these circumstances:

  • if the 100 limit has been reached, a change to any other field of one of the 'Protected' Leads will result in the error being reported incorrectly
  • where any kind of bulk update is done, the 100 limit isn't correctly enforced; e.g. if there are no 'Protected' Leads and 300 Leads are bulk updated to 'Protected' no errors will be reported

This code should avoid both of these problems (and with a bit more work it could be made to only do the query when necessary rather than all the time):

trigger ProtectedCap on Lead (before update) {
    // Count Leads not being updated by this trigger
    Integer protectedCount = [
            SELECT Count()
            FROM Lead
            WHERE Status = 'Protected'
            AND Id not in :Trigger.newMap.keySet()
            ];
    // Check Leads that are being updated by this trigger
    for (Lead myLead : Trigger.new) {
        if (myLead.Status == 'Protected') {
            protectedCount++;
        }
        if (protectedCount >= 100) {
            myLead.addError('Protected Leads are at 100, '
                    + 'please remove leads from Protected status to add.');
        }
    }
}

That then allows a more precise test to be written:

@isTest
private class testNewLeadCap {
    static testMethod void increment() {
        insert createLeads(98);
        try {
            insert createLeads(5);
            System.assert(false, 'Exception expected');
        } catch (DmlException e) {
            System.assertEquals(100 - 98 + 5, e.getNumDml());
        }
    }
    static testMethod void allAtOnce() {
        try {
            insert createLeads(103);
            System.assert(false, 'Exception expected');
        } catch (DmlException e) {
            System.assertEquals(103 - 100, e.getNumDml());
        }
    }
    private static Lead[] createLeads(Integer n) {
        Lead[] leads = new Lead[] {};
        for(Integer i = 0; i < n; i++) {
            leads.add(new Lead(
                    FirstName = 'Test' + i,
                    LastName = 'Testies' + i,
                    Status = 'Protected'
                    ));
        }
        return leads;
    }
}

that would fail for the original trigger.

11
  • First off... huge thanks! Ok so when I tried to save the trigger it gave me this error: :unexpected token: 'protected' at line 3 column 12
    – user8030
    Apr 23, 2014 at 17:08
  • @user8030 probably a reserved word. Use a different name.
    – Keith C
    Apr 23, 2014 at 17:48
  • ok done... now I'm getting: Illegal assignment from LIST<AggregateResult> to Integer at line 3 column 5
    – user8030
    Apr 23, 2014 at 18:03
  • @user8030 I've edited the answer - try it now.
    – Keith C
    Apr 23, 2014 at 18:28
  • 1
    One item to note, the trigger is on before update and all of the unit test code examples are performing insert operations.
    – Mark Pond
    Apr 23, 2014 at 18:49
0
test.startTest();
try
{
  insert leads;
  System.assert(false, 'It should have failed out before reaching this point.');
}catch(Exception e)
{

}
test.stopTest();  

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.