4

I'm still pretty new to programming and especially to SalesForce programming, but I would have expected this suite of trigger, handler class, and test class to:

  1. test as expected and
  2. show the test class covering my trigger + handler class.

But I am getting an error saying "expected: 3, actual: 4" out of executing the test class.

Furthermore, according to SalesForce, the test class doesn't cover any code.

What have I done wrong?

Thank you so much!

The trigger:

trigger LeadDeleteSpamTrigger on Lead (after insert) {
    // Only call the spam-record-deleting method if no methods in its class have yet fired
    if(!LeadDeleteSpamTriggerHandler.isRecursive) {
        // Call the method responsible for deleting spam records
        LeadDeleteSpamTriggerHandler.LeadDeleteSpamRecords(trigger.new);
    }
}

The handler class+method:

public class LeadDeleteSpamTriggerHandler {
    // Tell the world that no methods have run yet
    public static boolean isRecursive = false;
    // Method definition for LeadDeleteSpamRecords()
    public static void LeadDeleteSpamRecords(List<Lead> triggerLeads) {
        // Tell the world that this method has already run once
        isRecursive = true;

        // Loop through triggerLeads looking for ones to delete
        List<Lead> leadsToDelete = new List<Lead>();
        for (Lead l : triggerLeads) {
            if (l.get('LastName')=='[not provided]' && l.get('Company')=='[not provided]'){
                leadsToDelete.add(l);
            }
        }

        // Delete the leads that need to be deleted
        try {
            delete leadsToDelete;
        }
        catch (System.DmlException e) {
            System.debug('Database Error: Spam lead deletion failed.');
            for (Integer i = 0; i < e.getNumDml(); i++) {
                System.debug(e.getDmlMessage(i)); 
            }
        }
    }
}

The test class+method:

@istest
public class LeadDeleteSpamTriggerHandlerTest {
    static testMethod void test() {
        // Create a few leads in the database
        Lead l1 = new Lead(FirstName='AAAFakeLead', LastName='AFakeLastNameA', Company='Target'); // Should survive
        Lead l2 = new Lead(FirstName='BBBFakeLead', LastName='[not provided]', Company='Target'); // Should survive
        Lead l3 = new Lead(FirstName='CCCFakeLead', LastName='CFakeLastNameC', Company='[not provided]'); // Should survive
        Lead l4 = new Lead(FirstName='DDDFakeLead', LastName='[not provided]', Company='[not provided]'); // Should get deleted
        Test.startTest();
        insert l1;
        insert l2;
        insert l3;
        insert l4;
        Test.stopTest();
        // Query the database and see how many test leads exist (store it in a local variable "currentLeadCount")
        List<AggregateResult> resultQuery = [SELECT Count(Id) LeadCount FROM Lead WHERE FirstName LIKE '%FakeLead'];
        Integer currentLeadCount;
        if(resultQuery.size() > 0) {
            currentLeadCount = (Integer)resultQuery[0].get('LeadCount');
        } else {
            currentLeadCount = 0;
        }
        // Check if the number of test leads that exist is 3 (1 should have been deleted).
        system.assertEquals(3,currentLeadCount,'Wrong number of leads exist');
    }
}

The Debug Log: [old site - no longer available]

2
  • Do you have the debug log for a test run?
    – Mark Pond
    Commented Apr 15, 2015 at 17:30
  • Hi @MarkPond - yes I do. I added a link to it in the body of my question. Giving it a good look while cleaning up some company-specific text for posting here, I see that there isn't any sign that my attempt to peform a DELETE DML statement on leadsToDelete in the handler method invocation actually happened. But I'm not sure why. I appreciate your and others' attempt to help - thanks!
    – k..
    Commented Apr 15, 2015 at 19:21

1 Answer 1

1

At first you must change your test method. Insert all leads in one list enstead single inserts. this will help you with current exception

        List<Lead> leads = new List<Lead>{
        new Lead(FirstName='AAAFakeLead', LastName='AFakeLastNameA', Company='Target'),
        new Lead(FirstName='BBBFakeLead', LastName='[not provided]', Company='Target'),
        new Lead(FirstName='CCCFakeLead', LastName='CFakeLastNameC', Company='[not provided]'),
        new Lead(FirstName='DDDFakeLead', LastName='[not provided]', Company='[not provided]')
    };
    Test.startTest();
    insert leads;
    Test.stopTest();

But after that you will get other exception "DML statment cannot operate on trigger.new or trigger.old" because you get Leads for delete in Trigger. You can resolve it as in my example.

        // Loop through triggerLeads looking for ones to delete
    List<Id> leadsToDelete = new List<Id>();
    for (Lead l : triggerLeads) {
        if (l.get('LastName')=='[not provided]' && l.get('Company')=='[not provided]'){
            leadsToDelete.add(l.Id);
        }
    }

    // Delete the leads that need to be deleted
    try {
        Database.delete(leadsToDelete);
    }
2
  • Thanks, @nickzenko, it worked! Could you clarify, though, why going from performing a "delete [List<Lead>];" call to a "Database.delete[List<Id>]" call worked?
    – k..
    Commented Apr 16, 2015 at 19:51
  • @k.. you can't delete objects that you get in Trigger.new or old list. There are two ways how resolve this. First one - just send only Ids in Database.delete method(in that case method select rows for delete automaticaly, or at first select rows that you send to this method LeadDeleteSpamTriggerHandler.LeadDeleteSpamRecords([SELECT Id FROM Lead WHERE Id IN: trigger.newMap.keySet()]); - in that case you can delete objects like in your original code.
    – nickzenko
    Commented Apr 16, 2015 at 21:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .