function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Jason ElwongerJason Elwonger 

New Class & Trigger, can't test for code coverage?

Hello, I am trying to write a trigger to update a lookup field, I don't care if the update happens before or after insert, but best practices point me towards a before insert action. I managed to write a trigger and public class to complement it, but now I have 0% code coverage and I cannot seem to get a Test to run using the @isTest method.

Some backstory: I have a custom object called Plan Agent that includes a User lookup. I have another custom object called
Agent/District Assignment that also contains a User lookup. The goal is to dynamically fill a lookup filled called "Agent District Assignment" on the Plan Agent record, either when the record is being created or after it is created.

So my code currently looks like this:
 
Trigger:

trigger UpdateADA on Plan_Agent__c (before insert) {
    if (trigger.isBefore) 
    {
        if (trigger.isInsert) 
        {
            ADA_PlanAgentUpdateService.findADA(trigger.new);
        }
    }
}

Class:

public with sharing class ADA_PlanAgentUpdateService
{
    public static void findADA (List<Plan_Agent__c> records)
    {
        Set<String> planAgents = new Set<String>();
        for (Plan_Agent__c record : records) planAgents.add(record.Agent__c);
        
        Map<String, Agent_District_Assignment__c> dAssignments = new Map<String, Agent_District_Assignment__c>();
        for (Agent_District_Assignment__c dAssignment : [
            SELECT id FROM Agent_District_Assignment__c
            WHERE User__c IN :planAgents
        ]) dAssignments.put(dAssignment.Id, dAssignment);
        
        for (Plan_Agent__c record : records)
            if (dAssignments.containsKey(record.Agent__c))
                record.Agent_District_Assignment__c = dAssignments.get(record.Agent__c).Id;
    }
 }

Test Class:

@isTest
public with sharing class ADA_PlanAgentUpdateService
{
    public static void findADA (List<Plan_Agent__c> records)
    {
        Set<String> planAgents = new Set<String>();
        for (Plan_Agent__c record : records) planAgents.add(record.Agent__c);
        
        Map<String, Agent_District_Assignment__c> dAssignments = new Map<String, Agent_District_Assignment__c>();
        for (Agent_District_Assignment__c dAssignment : [
            SELECT id FROM Agent_District_Assignment__c
            WHERE User__c IN :planAgents
        ]) dAssignments.put(dAssignment.Id, dAssignment);
        
        for (Plan_Agent__c record : records)
            if (dAssignments.containsKey(record.Agent__c))
                record.Agent_District_Assignment__c = dAssignments.get(record.Agent__c).Id;
    }
    ADA_PlanAgentUpdateService.findADA(Trigger.new);
}

Any help would be greatly appreciated, thanks!
Best Answer chosen by Jason Elwonger
Joe BrodarJoe Brodar
Hey Jason,

I am glad that worked for the test class!

I think I found your issue in the class that is modifying the records. When creating the Map of ADA records, you are using the ADA record Id as the key value, but trying to match that against the User Id from the Agent__c field on the PA record. If you change the key value to the User__c instead of the Id field, I think that would fix it. See below:
public with sharing class ADA_PlanAgentUpdateService
{
    public static void findADA (List<Plan_Agent__c> records)
    {
        Set<String> planAgents = new Set<String>();
        // create set with UserId from Agent field on trigger records
        for (Plan_Agent__c record : records) planAgents.add(record.Agent__c);

        // create map of district_assignment record ids where the UserId matches the tirgger record UesrId
        Map<String, Agent_District_Assignment__c> dAssignments = new Map<String, Agent_District_Assignment__c>();
        for (Agent_District_Assignment__c dAssignment : [
            SELECT Id, User__c FROM Agent_District_Assignment__c
            WHERE User__c IN :planAgents
        ]) dAssignments.put(dAssignment.User__c, dAssignment); // this is where I think the issue was; you were putting the ADAssignemnt ID in the key, but trying to match it against the User Id from the record.Agent__c field

        for (Plan_Agent__c record : records)
        {
            if (dAssignments.containsKey(record.Agent__c)) record.Agent_District_Assignment__c = dAssignments.get(record.Agent__c).Id;
        }
    }
}
I hope that helps!

- Joe 

All Answers

Joe BrodarJoe Brodar
Hey Jason,

Instead of replicating the code in your trigger, all you need to do is make sure that the trigger is being activated by your test class. The easiest way to do this would be to just insert a Plan_Agent__c record in your test class. To make sure that it actually works, you will have to make sure that you are also inserting the records that the trigger would need (e.g. the matching Agent_District_Assignment__c record).
 
@isTest
public class UpdateADA_Test
{
    @isTest
    public static void testUpdateADA()
    {
        // insert your Agent_District_Assignment__c record and any others that will be needed in the trigger

        Plan_Agent__c pa = new Plan_Agent__c(Name = 'test'); // make sure you include all required fields, and any that will be used in the trigger

        Test.startTest();
        insert pa; // this will run the trigger before insert
        Test.stopTest();
    }
}

Let me know if that helps!

- Joe
Jason ElwongerJason Elwonger
Thanks Joe, I was able to run the test and it completed successfully! I checked my trigger and it is showing Code Coverage 100%

Now when I try to manually add a Plan Agent record through the interface I'm expecting the Agent District Assignment field to be filled by the trigger/class.  Unfortunately, it doesn't look like anything is happening. Is this a problem with my class? I thought the class would find the Agent/District Assignment record with the matching User Id from the Plan Agent record.

Thanks again for the test class help!

 
Joe BrodarJoe Brodar
Hey Jason,

I am glad that worked for the test class!

I think I found your issue in the class that is modifying the records. When creating the Map of ADA records, you are using the ADA record Id as the key value, but trying to match that against the User Id from the Agent__c field on the PA record. If you change the key value to the User__c instead of the Id field, I think that would fix it. See below:
public with sharing class ADA_PlanAgentUpdateService
{
    public static void findADA (List<Plan_Agent__c> records)
    {
        Set<String> planAgents = new Set<String>();
        // create set with UserId from Agent field on trigger records
        for (Plan_Agent__c record : records) planAgents.add(record.Agent__c);

        // create map of district_assignment record ids where the UserId matches the tirgger record UesrId
        Map<String, Agent_District_Assignment__c> dAssignments = new Map<String, Agent_District_Assignment__c>();
        for (Agent_District_Assignment__c dAssignment : [
            SELECT Id, User__c FROM Agent_District_Assignment__c
            WHERE User__c IN :planAgents
        ]) dAssignments.put(dAssignment.User__c, dAssignment); // this is where I think the issue was; you were putting the ADAssignemnt ID in the key, but trying to match it against the User Id from the record.Agent__c field

        for (Plan_Agent__c record : records)
        {
            if (dAssignments.containsKey(record.Agent__c)) record.Agent_District_Assignment__c = dAssignments.get(record.Agent__c).Id;
        }
    }
}
I hope that helps!

- Joe 
This was selected as the best answer
Jason ElwongerJason Elwonger
Great catch Joe! That is exactly what i was going for and your suggestion now has the trigger functioning correctly!

Thank you very much for all your help!