1

I've written a simple trigger to prevent duplication of a lead based on existing leads and contacts.

My test has 90% code coverage based on the tests that I've written to prevent lead duplication. However, when I attempt to insert some test contacts from my test class, the code coverage plummets to 0%.

I can successfully insert both leads and accounts but not contacts.

I am new to Apex so it's very possible this is a simple error on my part but I'm at a loss as to why this would happen.

Here's my trigger:

trigger PreventDupliciatesOnLeadBeforeInsert on Lead (before insert, before update) {
        Map<String, Lead> leadMap = new Map<String, Lead>();
        Set<string> allEmails = new Set<String>();

     for (Lead lead : System.Trigger.new) {

        // Make sure we don't treat an email address that 
        // isn't changing during an update as a duplicate. 
        if ((lead.Email != null) &&
                (System.Trigger.isInsert ||
                (lead.Email !=
                    System.Trigger.oldMap.get(lead.Id).Email))) {      
            allEmails.add(lead.Email); 


            if(ValidationHelper.checkIfExternalLead(lead.LeadSource)) {

            }  else {
                    // Make sure another new lead isn't also a duplicate 
                   if (leadMap.containsKey(lead.Email)) {
                       lead.Email.addError('Another new lead has the same email address.');
                   } else {
                       leadMap.put(lead.Email, lead);
                   }
            }
        }  
    }

    List<Contact> contactDuplicates = [SELECT email FROM Contact WHERE Email = :allEmails];


    for(Lead lead : System.Trigger.new) {
        if(lead.Email != null) {
            if(contactDuplicates.size() > 0) {
                lead.Email.addError('A contact with this email address already exists.');
            }
        }
    }


    // Using a single database query, find all the leads in 
    // the database that have the same email address as any 
    // of the leads being inserted or updated. 

    for (Lead lead : [SELECT Email, LeadSource FROM Lead WHERE Email IN :leadMap.KeySet()]) {
        Lead newLead = leadMap.get(lead.Email);
        if(!ValidationHelper.checkIfExternalLead(newLead.LeadSource)) {
            if (ValidationHelper.checkContactDuplicate(newLead.Email)) {
                newLead.Email.addError('A contact with this email address already exists.');
            } else {
                newLead.Email.addError('A lead with this email address already exists.');
            }
        }
    }
}

Here's my test class:

@istest public class PreventDuplicatesOnLeadBeforeInsertTests{
        static testMethod void testLeadDupPreventer() {  

      // First make sure there are no leads already in the system
      // that have the email addresses used for testing
      Set<String> testEmailAddress = new Set<String>();
      testEmailAddress.add('test1@duptest.com');
      testEmailAddress.add('test2@duptest.com');
      testEmailAddress.add('test3@duptest.com');
      testEmailAddress.add('test4@duptest.com');
      testEmailAddress.add('test5@duptest.com');
      System.assert([SELECT count() FROM Lead
                     WHERE Email IN :testEmailAddress] == 0);

      // Seed the database with some leads, and make sure they can
      // be bulk inserted successfully.
      Lead lead1 = new Lead(LastName='Test1', Company='Test1 Inc.',
                            Email='test1@duptest.com');
      Lead lead2 = new Lead(LastName='Test2', Company='Test2 Inc.',
                            Email='test4@duptest.com');
      Lead lead3 = new Lead(LastName='Test3', Company='Test3 Inc.',
                            Email='test5@duptest.com');
      Lead[] leads = new Lead[] {lead1, lead2, lead3};
      insert leads;

      Account account = new Account(Name='Test Account');
      insert account;

      Contact cont1 = new Contact(LastName='ContTest1', Email='test1contact@duptest.com', AccountId = account.Id, LeadSource
='Inbound Call');
      insert cont1;

      // Now make sure that some of these leads can be changed and
      // then bulk updated successfully. Note that lead1 is not
      // being changed, but is still being passed to the update
      // call. This should be OK.
      lead2.Email = 'test2@duptest.com';
      lead3.Email = 'test3@duptest.com';
      update leads;

      // Make sure that single row lead duplication prevention works
      // on insert.
      Lead dup1 = new Lead(LastName='Test1Dup',
                           Company='Test1Dup Inc.',
                           Email='test1@duptest.com');
      try {
         insert dup1;
         System.assert(false);
      } catch (DmlException e) {
         System.assert(e.getNumDml() == 1);
         System.assert(e.getDmlIndex(0) == 0);
         System.assert(e.getDmlFields(0).size() == 1);
         System.assert(e.getDmlFields(0)[0].getDescribe().getName() == 'Email');
         System.assert(e.getDmlMessage(0).indexOf(
            'A lead with this email address already exists.') > -1);
      }

      // Make sure that single row lead duplication prevention works
      // on update.
      dup1 = new Lead(Id = lead1.Id, LastName='Test1Dup',
                      Company='Test1Dup Inc.',
                      Email='test2@duptest.com');
      try {
         update dup1;
         System.assert(false);
      } catch (DmlException e) {
         System.assert(e.getNumDml() == 1);
         System.assert(e.getDmlIndex(0) == 0);
         System.assert(e.getDmlFields(0).size() == 1);
         System.assert(e.getDmlFields(0)[0].getDescribe().getName() == 'Email');
         System.assert(e.getDmlMessage(0).indexOf(
            'A lead with this email address already exists.') > -1);
        }

      // Make sure that bulk lead duplication prevention works on
      // insert. Note that the first item being inserted is fine,
      // but the second and third items are duplicates. Note also
      // that since at least one record insert fails, the entire
      // transaction will be rolled back.
      dup1 = new Lead(LastName='Test1Dup', Company='Test1Dup Inc.',
                      Email='test4@duptest.com');
      Lead dup2 = new Lead(LastName='Test2Dup',
                           Company='Test2Dup Inc.',
                           Email='test2@duptest.com');
      Lead dup3 = new Lead(LastName='Test3Dup',
                           Company='Test3Dup Inc.',
                           Email='test3@duptest.com');
      Lead[] dups = new Lead[] {dup1, dup2, dup3};
      try {
         insert dups;
         System.assert(false);
      } catch (DmlException e) {
         System.assert(e.getNumDml() == 2);
         System.assert(e.getDmlIndex(0) == 1);
         System.assert(e.getDmlFields(0).size() == 1);
         System.assert(e.getDmlFields(0)[0].getDescribe().getName() == 'Email');
         System.assert(e.getDmlMessage(0).indexOf(
            'A lead with this email address already exists.') > -1);
         System.assert(e.getDmlIndex(1) == 2);
         System.assert(e.getDmlFields(1).size() == 1);
         System.assert(e.getDmlFields(1)[0].getDescribe().getName() == 'Email');
         System.assert(e.getDmlMessage(1).indexOf(
            'A lead with this email address already exists.') > -1);
      }

      // Make sure that bulk lead duplication prevention works on
      // update. Note that the first item being updated is fine,
      // because the email address is new, and the second item is
      // also fine, but in this case it's because the email
      // address doesn't change. The third case is flagged as an
      // error because it is a duplicate of the email address of the
      // first lead's value in the database, even though that value
      // is changing in this same update call. It would be an
      // interesting exercise to rewrite the trigger to allow this
      // case. Note also that since at least one record update
      // fails, the entire transaction will be rolled back.
      dup1 = new Lead(Id=lead1.Id, Email='test4@duptest.com');
      dup2 = new Lead(Id=lead2.Id, Email='test2@duptest.com');
      dup3 = new Lead(Id=lead3.Id, Email='test1@duptest.com');
      dups = new Lead[] {dup1, dup2, dup3};
      try {
         update dups;
         System.assert(false);
      } catch (DmlException e) {
         System.debug(e.getNumDml());
         System.debug(e.getDmlMessage(0));
         System.assert(e.getNumDml() == 1);
         System.assert(e.getDmlIndex(0) == 2);
         System.assert(e.getDmlFields(0).size() == 1);
         System.assert(e.getDmlFields(0)[0].getDescribe().getName() == 'Email');
         System.assert(e.getDmlMessage(0).indexOf(
            'A lead with this email address already exists.') > -1);
        }

      // Make sure that duplicates in the submission are caught when
      // inserting leads. Note that this test also catches an
      // attempt to insert a lead where there is an existing
      // duplicate.
      dup1 = new Lead(LastName='Test1Dup', Company='Test1Dup Inc.',
                      Email='test4@duptest.com');
      dup2 = new Lead(LastName='Test2Dup', Company='Test2Dup Inc.',
                      Email='test4@duptest.com');
      dup3 = new Lead(LastName='Test3Dup', Company='Test3Dup Inc.',
                      Email='test3@duptest.com');
      dups = new Lead[] {dup1, dup2, dup3};
      try {
         insert dups;
         System.assert(false);
      } catch (DmlException e) {
         System.assert(e.getNumDml() == 2);
         System.assert(e.getDmlIndex(0) == 1);
         System.assert(e.getDmlFields(0).size() == 1);
         System.assert(e.getDmlFields(0)[0].getDescribe().getName() == 'Email');
         System.assert(e.getDmlMessage(0).indexOf(
            'Another new lead has the same email address.') > -1);
         System.assert(e.getDmlIndex(1) == 2);
         System.assert(e.getDmlFields(1).size() == 1);
         System.assert(e.getDmlFields(0)[0].getDescribe().getName() == 'Email');
         System.assert(e.getDmlMessage(1).indexOf(
            'A lead with this email address already exists.') > -1);
      }

      // Make sure that duplicates in the submission are caught when
      // updating leads. Note that this test also catches an attempt
      // to update a lead where there is an existing duplicate.
      dup1 = new Lead(Id=lead1.Id, Email='test4@duptest.com');
      dup2 = new Lead(Id=lead2.Id, Email='test4@duptest.com');
      dup3 = new Lead(Id=lead3.Id, Email='test2@duptest.com');
      dups = new Lead[] {dup1, dup2, dup3};
      try {
         update dups;
         System.assert(false);
      } catch (DmlException e) {
         System.assert(e.getNumDml() == 2);
         System.assert(e.getDmlIndex(0) == 1);
         System.assert(e.getDmlFields(0).size() == 1);
         System.assert(e.getDmlFields(0)[0].getDescribe().getName() == 'Email');
         System.assert(e.getDmlMessage(0).indexOf(
            'Another new lead has the same email address.') > -1);
         System.assert(e.getDmlIndex(1) == 2);
         System.assert(e.getDmlFields(1).size() == 1);
         System.assert(e.getDmlFields(1)[0].getDescribe().getName() == 'Email');
         System.assert(e.getDmlMessage(1).indexOf(
            'A lead with this email address already exists.') > -1);
      }    } }

Also, there are no errors. The test runs successfully without the insert statement and has coverage of 90%. The test runs successfully with the insert statement but comes up with 0%.

  • 1
    What error do you get when the test fails? – Jenny B Aug 12 '14 at 15:44
  • 2
    Also please post your test class – Rao Aug 12 '14 at 15:46
  • 1
    welcome to sfse, as you can see from the previous comments, having more context and information on your question can usually help us a lot. By editing you could update the question and provide more information. Relevant details are often error messages, what you're trying to do, what you've done to debug your issue, and simplified code specific to the issue that's happening. Help us help you :) – Samuel De Rycke Aug 12 '14 at 15:50
  • Made some edits! – Cara Conner Aug 12 '14 at 16:04
  • Have you tried clearing the test data and/or opening the class in the developer console and making a small edit and resaving, then rerun the test. I remember reading something similar awhile back. – Jenny B Aug 12 '14 at 18:17

Your Answer

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

Browse other questions tagged or ask your own question.