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
SidViciousSidVicious 

Help with Test Class Issue To Improve Code Coverage

Hi experts, I'm trying to create a Test class for my trigger handler however can't seem to progress. My trigger is a simple AFTER UPDATE that fires whenever the CurrencyIsoCode is changed for the Opportunity record.

A code snippet from my trigger handler follows below:
public class OpportunityTriggerHandler extends TriggerHandler

private void updateCurrencyIsoCode(){

        for(Opportunity__c  oppty : (List<Opportunity__c>) Trigger.new){
            Opportunity__c oldOppty = (Opportunity__c)Trigger.oldMap.get(oppty.Id);

            if (oppty.CurrencyIsoCode != oldOppty.CurrencyIsoCode){

                opptyList.add(oppty);
            }  
        }
    }

I keep failing coverage for this line, as shown above.
opptyList.add(oppty);

Finally, here is my test class:
@isTest
    private static void updateInvoiceFields()
    {
        Opportunity__c opportunityRecord = new Opportunity__c();
        opportunityRecord.Account__c = '0012x000002kyl7AAA';
        opportunityRecord.CurrencyIsoCode = 'USD';
        opportunityRecord.Organisation__c = 'Default';
        insert opportunityRecord;

        List<Opportuntiy__c> opportunityRecordList = new List<Opportunity__c>();
        opportunityRecordList.add(opportunityRecord);

        Test.startTest();
            System.assertNotEquals(0, opportunityRecordList.size());
            for(Opportunity__c opportunityRecord : opportunityRecordList){
                System.assertNotEquals(opportunityRecord.CurrencyIsoCode, 'HKD');
                opportunityRecord.CurrencyIsoCode = 'HKD';
                System.assertEquals(opportunityRecord.CurrencyIsoCode, 'HKD');
            }
            try
            {
                update opportunityRecordList;
            }Catch(Exception e)
            {
                String errormessage = e.getMessage();
                system.debug(errormessage);
            }
        Test.stopTest();
    }

So, I changed the field as shown above however am not able to achieve coverage. By the way, all my assertions above passed.

What am I missing or doing wrong?

Thanks!

- Sid
Best Answer chosen by SidVicious
SidViciousSidVicious
It turns out it was due to the current structuring of methods in my OpportunityTriggerHandler class. I have separated my code into different methods and once I have put combined them into just one, I was able to get the needed code coverage. 
 
private static Boolean isFirstTime = true;

public override void afterUpdate() {
        
        if(OpportunityTriggerHandler.isFirstTime){
            
            OpportunityTriggerHandler.isFirstTime = false;

            updateCurrencyIsoCode(); // This is the method in discussion
            updateInvoiceFields(); // Method containing the logic
            updateData(); // Updates the records
        }
    }

If anyone knows how to make a Test class for the above mentioned, I'd appreciate any further suggestions. But at the moment, I got code coverage, so I think all is well.

Much thanks to @Anudeep and @Andrew G for the ideas and suggestions.

All Answers

AnudeepAnudeep (Salesforce Developers) 
Test class is not covering the line you specified because the following criteria is not being met through data inserted through test class

if (oppty.CurrencyIsoCode != oldOppty.CurrencyIsoCode){

I suggest updating the opportunity in the same transaction
 
Opportunity__c opportunityRecord = new Opportunity__c();         opportunityRecord.Account__c = '0012x000002kyl7AAA';         opportunityRecord.CurrencyIsoCode = 'USD';         opportunityRecord.Organisation__c = 'Default';         insert opportunityRecord;
       opportunityRecord.CurrencyIsoCode = 'HKD' 
       update opportunityRecord.CurrencyIsoCode
      OpportunityTriggerHandler opp = new OpportunityTriggerHandler(); 
      opp.oldOppty = opportunityRecord;

I also recommend looking at the following examples

https://salesforce.stackexchange.com/questions/98760/how-to-cover-trigger-oldmap-get-area-in-test-class

https://salesforce.stackexchange.com/questions/252733/how-to-cover-trigger-oldmap-get-in-test-class

Let me know if this helps

Anudeep
Andrew GAndrew G
Hi Sid

try switching out these lines:
List<Opportuntiy__c> opportunityRecordList = new List<Opportunity__c>();
        opportunityRecordList.add(opportunityRecord);
with:
List<Opportuntiy__c> opportunityRecordList = new List<Opportunity__c>();
opportunityRecordList = [SELECT Id, Name, CurrencyIsoCode FROM Opportunity WHERE Id = :opportunityRecord.Id];
I suspect / wonder if the issue relates to the concept of "in memory" test records and test records "written to disk".

Regards
Andrew

 
SidViciousSidVicious
It turns out it was due to the current structuring of methods in my OpportunityTriggerHandler class. I have separated my code into different methods and once I have put combined them into just one, I was able to get the needed code coverage. 
 
private static Boolean isFirstTime = true;

public override void afterUpdate() {
        
        if(OpportunityTriggerHandler.isFirstTime){
            
            OpportunityTriggerHandler.isFirstTime = false;

            updateCurrencyIsoCode(); // This is the method in discussion
            updateInvoiceFields(); // Method containing the logic
            updateData(); // Updates the records
        }
    }

If anyone knows how to make a Test class for the above mentioned, I'd appreciate any further suggestions. But at the moment, I got code coverage, so I think all is well.

Much thanks to @Anudeep and @Andrew G for the ideas and suggestions.
This was selected as the best answer