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
Alex DornAlex Dorn 

Writing test class

I spent all of yesterday trying to write test classes for my two new triggers, but with zero experience with coding it has been a very difficult process.  All the apex triggers do is update the Last_activity_type__c field when a new activity is logged. Is there anyone who can help me write the test class code? Here are my triggers:
List<Id> OpportunityIds = new List<Id>();
List<Opportunity> OpportunityList = new List<Opportunity>();

for(Task t :trigger.new)
    {
    if(t.whatid!=null)
    {
        Schema.SObjectType tType= t.whatid.getSObjectType();
        if(tType == Opportunity.Schema.SObjectType)
        {
            OpportunityIds.add(t.Whatid);
        }
    }
    }
    {
    //Querying the related Opportunity based on whatid on Task
    Map<Id,Opportunity> OpportunityMap =  new Map<Id,Opportunity>([select id,Last_Activity_Subject__C from Opportunity where id in:OpportunityIds]);
 
    for(Task t :Trigger.new)

        for(Opportunity l : OpportunityMap.Values())
        {
            l.Last_Activity_Subject__C = t.subject;
            OpportunityList.add(l);
        }
    }
    // updating the Opportunity
    if(OpportunityList.size()>0)
    {
        update OpportunityList;
    }
}

trigger updateRelatedLead on Task (after insert,after update) {

List<Id> LeadIds = new List<Id>();
List<Lead> LeadList = new List<Lead>();

for(Task t :trigger.new)
    {
    if(t.whoId!=null)
    {
        Schema.SObjectType tType= t.whoId.getSObjectType();
        if(tType == Lead.Schema.SObjectType)
        {
            LeadIds.add(t.WhoId);
        }
    }
    }
    {
    //Querying the related Lead based on whoId on Task
    Map<Id,Lead> LeadMap =  new Map<Id,Lead>([select id,Last_Activity_Subject__C from Lead where id in:LeadIds]);
 
    for(Task t :Trigger.new)

        for(Lead l : LeadMap.Values())
        {
            l.Last_Activity_Subject__C = t.subject;
            LeadList.add(l);
        }
    }
    // updating the Lead
    if(LeadList.size()>0)
    {
        update LeadList;
    }
}
Best Answer chosen by Alex Dorn
magicforce9magicforce9
Hi Alex,

Hopefully this work, I have revised the trigger and test class....Please see my comments

trigger updateRelatedLeadOrOpportunity on Task (after insert,after update) {
List<Id> OpportunityIds = new List<Id>();
List<Opportunity> OpportunityList = new List<Opportunity>();
List<Id> LeadIds = new List<Id>();
List<Lead> LeadList = new List<Lead>();
List<Task> taskToProcess = new List<Task>();

    for(Task t :trigger.new)
        {
        //This will make sure that we only process the task who's subject is added/updated
        if(t.subject != null && (trigger.isInsert || trigger.newMap.get(t.id).subject != trigger.oldMap.get(t.id).subject)){
            //You'll have WhoId populated when the Task related to a Lead/Contact(only) 
            //and whatId will be populated if the task is realted to Account/Opportunity/Custom Objects...
            if(t.whatId !=null)
            {
                Schema.SObjectType tType= t.whatid.getSObjectType();
                if(tType == Opportunity.Schema.SObjectType)
                {
                    OpportunityIds.add(t.Whatid);
                    taskToProcess.add(t);
                }
                
            }

            if(t.whoId != null){

                Schema.SObjectType tType= t.whoId.getSObjectType();
                if(tType == Lead.Schema.SObjectType)
                {
                    LeadIds.add(t.whoId);
                    taskToProcess.add(t);
                }
            }
        
        
        }   
    }
    
    //Querying the related Opportunity as well as Lead based on whatid on Task
    Map<Id,Opportunity> OpportunityMap =  new Map<Id,Opportunity>([select id,Last_Activity_Subject__C from Opportunity where id in:OpportunityIds]);
    Map<Id,Lead> LeadMap =  new Map<Id,Lead>([select id,Last_Activity_Subject__C from Lead where id in:LeadIds]);
    }
    //Now we have all the tasks that we need to process in this loop
    for(Task t :taskToProcess){
        if(t.whatid!=null)
        {
            Schema.SObjectType tType= t.whatId.getSObjectType();
            if(tType == Opportunity.Schema.SObjectType){
                Opportunity opp = OpportunityMap.get(t.whatId);
                opp.Last_Activity_Subject__C = t.subject;
                OpportunityList.add(opp);
            }
            

        }
        
        if(t.whoId!=null){
            Schema.SObjectType tType= t.whoId.getSObjectType();
            if(tType == Lead.Schema.SObjectType){
                Lead lead = LeadMap.get(t.whoId);
                lead.Last_Activity_Subject__C = t.subject;
                LeadList.add(lead);
            }

        }
    }
    // updating the Opportunity and lead
    if(!OpportunityList.isEmpty()) update OpportunityList;
    if(!LeadList.isEmpty()) update LeadList;
    
}

And the test class....
@istest 
public class TestupdateRelatedLeadOrOpportunity{

    private Static testmethod void TestLastActivitUpdateSubject(){
        
        //You'll need to populate data into all other required fields and with respect to any validation rules if you have any.
        Lead l = new Lead(Firstname = 'TestFName'. Lastname = 'TestLName');
        insert l;

        //You'll need to populate data into all other required fields and with respect to any validation rules if you have any.
        Account a = new Account(Name = 'Test Account');
        insert a;
        Opportunity o = new Opportunity(Name = 'Test Oppotunity'. AccountId = a.id);
        insert o;

        //These tasks will be related to Lead & Opportunity hence it will cause the trigger to execute and upadte the task Subject to Last_Activity_Subject__C field
        List<task> t = new List<task>{ new task(WhoID = l.id, Subject='Call', Status='Completed', Priority='Normal'), new task(WhatID = o.id, Subject='Email', Status='Completed', Priority='Normal')};
        insert t;
        Lead lead = [select Last_Activity_Subject__C from Lead where id = :l.id];
        Opportunity opp = [select id,Last_Activity_Subject__C from Opportunity where id = :o.id];
        System.assertEquals('Call', lead.Last_Activity_Subject__C);
        System.assertEquals('Email', opp.Last_Activity_Subject__C);
    }
}


All Answers

Alex DornAlex Dorn
Hi magicforce thanks for the help I ran into a couple problems when putting in the new trigger and the test. When implementing the trigger I had to add a semicolon to the end of lines 35 and 40. I also had to change 39 from l. to lead. When I record an activity on and opportunity it works perfectly however when I attempt to record an activity on a lead I get the error "Apex trigger updateRelatedLeadOrOpportunity caused an unexpected exception, contact your administrator: updateRelatedLeadOrOpportunity: execution of AfterInsert caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.updateRelatedLeadOrOpportunity: line 29, column 1" And I attempted deleting line 29 and changing "tType" to "t.type" in lines 32 and 37 but then I got an error attempting to record an activity in line 39. 
After this I tried using the test class you wrote with my current triggers I did have to change the periods in lines 7 and 13 to a comma. When I ran the test though it said it failed. I may be running the test wrong (I've never ran a test before) or need to change something in the code to use it with my trigger names.
Alex DornAlex Dorn
The trigger works for opportunities and now allows Activities to be logged for leads but still does not insert the subject, and when converting leads I get this error Error: System.DmlException: Update failed. First exception on row 0 with id 00TJ000000RNXg7MAH; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, updateRelatedLeadOrOpportunity: execution of AfterUpdate caused by: System.ListException: Duplicate id in list: 006J000000FrcF2IAJ Trigger.updateRelatedLeadOrOpportunity: line 46, column 1: [] (System Code). The test has this error System.DmlException: Insert failed. First exception on row 0; first error: FIELD_INTEGRITY_EXCEPTION, Opportunity/Account ID: id value of incorrect type: 00QJ0000007ubuDMAQ: [WhatId]. The test isn't a huge concern though because as of this point it has 76% coverage.
magicforce9magicforce9
Hi Alex,

Hopefully this work, I have revised the trigger and test class....Please see my comments

trigger updateRelatedLeadOrOpportunity on Task (after insert,after update) {
List<Id> OpportunityIds = new List<Id>();
List<Opportunity> OpportunityList = new List<Opportunity>();
List<Id> LeadIds = new List<Id>();
List<Lead> LeadList = new List<Lead>();
List<Task> taskToProcess = new List<Task>();

    for(Task t :trigger.new)
        {
        //This will make sure that we only process the task who's subject is added/updated
        if(t.subject != null && (trigger.isInsert || trigger.newMap.get(t.id).subject != trigger.oldMap.get(t.id).subject)){
            //You'll have WhoId populated when the Task related to a Lead/Contact(only) 
            //and whatId will be populated if the task is realted to Account/Opportunity/Custom Objects...
            if(t.whatId !=null)
            {
                Schema.SObjectType tType= t.whatid.getSObjectType();
                if(tType == Opportunity.Schema.SObjectType)
                {
                    OpportunityIds.add(t.Whatid);
                    taskToProcess.add(t);
                }
                
            }

            if(t.whoId != null){

                Schema.SObjectType tType= t.whoId.getSObjectType();
                if(tType == Lead.Schema.SObjectType)
                {
                    LeadIds.add(t.whoId);
                    taskToProcess.add(t);
                }
            }
        
        
        }   
    }
    
    //Querying the related Opportunity as well as Lead based on whatid on Task
    Map<Id,Opportunity> OpportunityMap =  new Map<Id,Opportunity>([select id,Last_Activity_Subject__C from Opportunity where id in:OpportunityIds]);
    Map<Id,Lead> LeadMap =  new Map<Id,Lead>([select id,Last_Activity_Subject__C from Lead where id in:LeadIds]);
    }
    //Now we have all the tasks that we need to process in this loop
    for(Task t :taskToProcess){
        if(t.whatid!=null)
        {
            Schema.SObjectType tType= t.whatId.getSObjectType();
            if(tType == Opportunity.Schema.SObjectType){
                Opportunity opp = OpportunityMap.get(t.whatId);
                opp.Last_Activity_Subject__C = t.subject;
                OpportunityList.add(opp);
            }
            

        }
        
        if(t.whoId!=null){
            Schema.SObjectType tType= t.whoId.getSObjectType();
            if(tType == Lead.Schema.SObjectType){
                Lead lead = LeadMap.get(t.whoId);
                lead.Last_Activity_Subject__C = t.subject;
                LeadList.add(lead);
            }

        }
    }
    // updating the Opportunity and lead
    if(!OpportunityList.isEmpty()) update OpportunityList;
    if(!LeadList.isEmpty()) update LeadList;
    
}

And the test class....
@istest 
public class TestupdateRelatedLeadOrOpportunity{

    private Static testmethod void TestLastActivitUpdateSubject(){
        
        //You'll need to populate data into all other required fields and with respect to any validation rules if you have any.
        Lead l = new Lead(Firstname = 'TestFName'. Lastname = 'TestLName');
        insert l;

        //You'll need to populate data into all other required fields and with respect to any validation rules if you have any.
        Account a = new Account(Name = 'Test Account');
        insert a;
        Opportunity o = new Opportunity(Name = 'Test Oppotunity'. AccountId = a.id);
        insert o;

        //These tasks will be related to Lead & Opportunity hence it will cause the trigger to execute and upadte the task Subject to Last_Activity_Subject__C field
        List<task> t = new List<task>{ new task(WhoID = l.id, Subject='Call', Status='Completed', Priority='Normal'), new task(WhatID = o.id, Subject='Email', Status='Completed', Priority='Normal')};
        insert t;
        Lead lead = [select Last_Activity_Subject__C from Lead where id = :l.id];
        Opportunity opp = [select id,Last_Activity_Subject__C from Opportunity where id = :o.id];
        System.assertEquals('Call', lead.Last_Activity_Subject__C);
        System.assertEquals('Email', opp.Last_Activity_Subject__C);
    }
}


This was selected as the best answer
Alex DornAlex Dorn
For the trigger i am getting an unexpected token: For at line 44 error
Alex DornAlex Dorn
I deleted the } at line 42 and that seemed to solve the problem
Alex DornAlex Dorn
That works now and passes with 100% code coverage thank you so much