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
Mayank.msMayank.ms 

Test class coverage issue when updating contact object custom field from opportunity

Hello everyone,
I have created a trigger which will update Contact Object field(Most_recent_Opportunity_Stage__c) whenever opportunity status gets changed.
My trigger is working fine but associated Test class is not making 75% code coverage of Trigger. I am new to salesforce and not having much experince to build test class so please help me.

Here is my Trigger and associated test class :

Trigger :

trigger UpdateMostRecentOpportunityStageOfContact on Opportunity (after update) {
  Set<String> ContactIds = new Set<String>();
     Set<String> oppIds = new Set<String>();
     if(UpdateStageOnContactHandler.isFirstTime){
             UpdateStageOnContactHandler.isFirstTime=false;
    List<OpportunityContactRole> conList = new List<OpportunityContactRole>([select ContactId from OpportunityContactRole where IsPrimary = true and OpportunityId IN :Trigger.newMap.keySet() limit 1]);
     for(OpportunityContactRole c :conList)
       {
           ContactIds.add(c.ContactId);
       }    
    List<OpportunityContactRole> oppList =  new List<OpportunityContactRole>([select ContactId,opportunityId,CreatedDate from OpportunityContactRole where IsPrimary = true and ContactId =: ContactIds order by CreatedDate desc  limit 1]);
    for(OpportunityContactRole cr :oppList)
       {
           oppIds.add(cr.opportunityId);
       } 
    if(!oppIds.isEmpty()){
    Opportunity op = [select StageName from opportunity where Id =:oppIds limit 1]; 
    List<Contact> contactToUpdate = new List<Contact>();
    for(Opportunity opp : trigger.new){
           for(OpportunityContactRole c :oppList){ 
                if(opp.AccountId != null){
                 contactToUpdate.add(new Contact(Id = c.ContactId, Most_recent_Opportunity_Stage__c=op.StageName)); 
               }
           }    
       }
       if (contactToUpdate != null && !contactToUpdate.isEmpty())
        {
            Update contactToUpdate;
        } 
     }
   }      
 }


TEST Class :

@isTest
public class TestUpdateMostRecentopportunityStage {
   static testMethod void TestUpdateStageOnContactTest()
    {   
        Account a = new Account(Name = 'TestUpdateStageOnContactTest');
        a.Type = 'Prospect';
        insert a;

        Contact newContact1 = new Contact(Lastname='TestUpdateStageOnContactTest1', AccountId = a.Id ,Email='mayanks+test1@webgility.com' );
        insert newContact1;
        
        Contact newContact2 = new Contact(Lastname='TestUpdateStageOnContactTest2', AccountId = a.Id ,Email='mayanks+test2@webgility.com' );
        insert newContact2;
    
      
        Opportunity o1 = new Opportunity(AccountId=a.Id, name='OPP test1', StageName='Demo', CloseDate = Date.today() );
       insert o1;
        OpportunityContactRole ocr1 = new OpportunityContactRole(OpportunityId = o1.Id, ContactId = newContact1.Id, Role='Decision Maker',Isprimary=true );
        insert ocr1;
        
          Opportunity o2 = new Opportunity(AccountId=a.Id, name='OPP test2', StageName='Open', CloseDate = Date.today() );
       insert o2;
        OpportunityContactRole ocr2 = new OpportunityContactRole(OpportunityId = o2.Id, ContactId = newContact2.Id, Role='Decision Maker',Isprimary=true );
        insert ocr2;
        
          Test.StartTest();
        o1.stageName='Demo';
        update o1;
        newContact1.Most_recent_Opportunity_Stage__c='Demo';
        update newContact1;
        
         o2.stageName='Open';
        update o2;
        newContact2.Most_recent_Opportunity_Stage__c='Open';
        update newContact2;
        
        Test.StopTest();
         
      }   
}


Thanks,
Mayank
sfdcMonkey.comsfdcMonkey.com
Hi mayank,  your test class seems ok. can you please share test class failure exception. 
 
Mukesh_SfdcDevMukesh_SfdcDev
Hi Mayank,

@Mayank, @Piyush is right please post your exception also so that find the exact problem. I reviewed your code there are some best practices is miss. Please see some below points.
  • don't every time update the same instance of an object instead of preparing a list and update or insert only one time(in your code line no:28, 33 and 30,35).
  • No need to update a contact in this code.
  • In this code put test. start after declaring the method.

hope this will help you.

Thanks
Mukesh
v varaprasadv varaprasad
Hi Mayank,

Please add a contact in opportunity also.

  Opportunity o1 = new Opportunity(AccountId=a.Id, name='OPP test1', StageName='Demo', CloseDate = Date.today(), ContactId = newContact1.Id );
       insert o1;

Hope this helps you!
If my answer helps resolve your query, please mark it as the 'Best Answer' & upvote it to benefit others.

Thanks
Varaprasad
@For Support: varaprasad4sfdc@gmail.com
Mayank.msMayank.ms
@ v varaprasad : It will not work as ContactId field is not directly associated with Opportunity and that's why It is showing error after adding contactId in opportunity. The error is : Field does not exist: ContactId on opportunity
Mayank.msMayank.ms
@Mukesh_SfdcDev , {!Piyush_soni__c} : I am not getting any excpetion or error my test class runs susccessfully . But I am having problem with code coverage . My test class is not covering 75% coverage as my Trigger UpdateMostRecentOpportunityStageOfContact  is showing only 42% coverage but I need atleast 75% so that I can deploy it on production. Here is my updated test class which covering 42% coverage Ignore prevoius one. Please let me know what I need to add in test class to make 75 % coverage .

I have also attached a screen shot of my trigger coverage where red lines are not being coevered.

Test Class :
@isTest
public class TestUpdateMostRecentopportunityStage {
   static testMethod void TestUpdateStageOnContactTest()
  {   
    Account a = new Account(Name = 'TestUpdateStageOnContactTest');
    a.Type = 'Prospect';
    insert a;

    Contact newContact = new Contact(Lastname='TestUpdateStageOnContactTest', AccountId = a.Id ,Email='mayank06@gmail.com' );
    insert newContact;
  
        String opportunityName = 'TestUpdateStageOnContactTest';
      
        Opportunity o2 = new Opportunity(AccountId=a.Id, name='OPP test1', StageName='Demo', CloseDate = Date.today() );
       insert o2;
        OpportunityContactRole ocr1 = new OpportunityContactRole(OpportunityId = o2.Id, ContactId = newContact.Id, Role='Decision Maker',Isprimary=true );
    insert ocr1;
    
          Test.StartTest();
        o2.stageName='Demo';
        update o2;
        newContact.Most_recent_Opportunity_Stage__c='Demo';
        update newContact;
        
        Test.StopTest();
         
      }   
}



User-added image
Mayank.msMayank.ms
Can anyone help on this ?
Mukesh_SfdcDevMukesh_SfdcDev
Hi Mayank,

I have done some changes in your code. Have a look
@isTest
public class TestUpdateMostRecentopportunityStage {
    static testMethod void TestUpdateStageOnContactTest() {
        
        Test.StartTest();

        Account acc = new Account(Name = 'TestUpdateStageOnContactTest');
        acc.Type = 'Prospect';
        insert acc;
		System.assertNotEquals(null,acc.Id);

        Contact newContact = new Contact(Lastname = 'TestUpdateStageOnContactTest', AccountId = acc.Id, Email = 'mayank06@gmail.com');
        insert newContact;
		System.assertNotEquals(null,newContact.Id);

        Opportunity opp = new Opportunity(AccountId = acc.Id, name = 'OPP test1', StageName = 'Demo', CloseDate = Date.today());
        insert opp;
		System.assertNotEquals(null,opp.Id);
		
        OpportunityContactRole OppRole = new OpportunityContactRole(OpportunityId = opp.Id, ContactId = newContact.Id, Role = 'Decision Maker', Isprimary = true);
        insert OppRole;
		System.assertNotEquals(null,OppRole.Id);

        opp.stageName = 'ClosedWon';
        update opp;    

        Test.StopTest();

    }
}

Hope this will help you.

Thanks
Mukesh Kumar
Mayank.msMayank.ms
@Mukesh Thanks Mukesh for your reply but still it is giving same coverage 42%... Can you please see the screen shot I attached in my previous reply? You can see the red lines which need to be covered.
Mukesh_SfdcDevMukesh_SfdcDev
Hi Mayank,

This code working fine in my org. In your screenshot line no-6, query does not return any value so that the conList remain blank so that code coverage falls below 75%. Could you please add (seeAllData = true) in your test class. Are you the administrator of this org?

Thanks
Mukesh Kumar

 
Mayank.msMayank.ms

Hi Mukesh,
Thnaks for your efforts, Yes I am the administrator  and I tried your solution of adding  (seeAllData = true) but still the coverage is 42%. I tried to add  (seeAllData = true) before class declartion and also tried to add it before test method but still having issue with coverage. 

Mukesh_SfdcDevMukesh_SfdcDev
Hi Mayank,

Everything in code is looking fine. You have to add the debug statement in the code and debug the code line by line.
In the apex class line no-6, query return zero records here is the main problem. Please identify why this query returns zero records.

Thanks
Mukesh Kumar
 
Mayank.msMayank.ms
Hi Mukesh,
As you told that In the apex class line no-6, query return zero records but I checked the trigger in sandbox and It is working fine and doing same thing for which I have  created it . It is actaully updating the contact field  as opportunity stage gets updated. I am just having problem with Test coverage. Can you tell me what coverage is showing at your end?
Mukesh_SfdcDevMukesh_SfdcDev
Hi Mayank,

In my Org is shows class have 100% code coverage.

User-added image

How many triggers have you written on the opportunity object?
I think there is some confliction exist to prevent increase the code coverage.

Thanks
Mukesh Kumar
Mayank.msMayank.ms

Hi Mukesh,
There are around 23 triggers on opportunity Object. Out of them 13 are Active.

Thanks,
Mayank

Mukesh_SfdcDevMukesh_SfdcDev
Hi Mayank,

Just take a backup like a screenshot of list of the trigger and then deactivate all the trigger except "UpdateMostRecentOpportunityStageOfContact" after that run the apex class.
On any object, more than one trigger is not a best practice because in the salesforce there is no order define which trigger will execute first.

Thanks
Mukesh Kumar
 
Mayank.msMayank.ms
Hi Mukesh,
I can understand but each trigger has been implmented for differnt purpose and they are required to be there. No trigger is related to UpdateMostRecentOpportunityStageOfContact. So can this be a issue ?

Thanks,
Mayank
Mukesh_SfdcDevMukesh_SfdcDev
Hi Mayank,

More than one trigger always create a problem to manage the logic.
As per my suggestion please do it one time.

Thanks
Mukesh Kumar
Mayank.msMayank.ms
Hi Mukesh,

Thanks for you help and time. I will check it if there is some issue from other trigger. 
Mukesh_SfdcDevMukesh_SfdcDev
Hi Mayank,

Your wlc.

Thanks
Mukesh Kumar