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
Nick SpeyerNick Speyer 

Help on Test Method for Trigger similar to VLOOKUP

Hi everybody,

I've got a trigger i've been working on that does all the requirements I need it to. I am at the final stretch of deployment and need to write a test method that will give me adequate code coverage to deploy.

The basis of the code is very similar to a VLOOKUP function. I have a set of 700+ records which include a zip code in the name field and a specific "Load Zone" in the second field. My code keys off of an updated parcel zip code in the opportunity object as a reference and returns the proper load zone for that zip code from the list of records - again, much like a VLOOKUP. I now have to develop test methods to ensure code coverage. Is anybody willing to help?

The Trigger is as follows:

Parcel_Zip__c is the field in Opportunity being referenced in the Load_U__c object that holds the name field being searched through and returning the corresponding Load_Zone__c field's value into the Load_Zone_Utility_4__C field in the opportunity object.
 
Trigger updateLZU on Opportunity (before insert, before update) {

	set <string> ZipCodes = new Set <string>( ); 
	//creates a set labeled zip codes to hold the Parcel Zip Codes being referenced 

	for ( opportunity l : trigger.new) {
	
		If ( l.Parcel_Zip__c != null) {
	
			ZipCodes.add (l.Parcel_Zip__c);}
	}
	//loads the Parcel Zip Code field values into the ZipCodes set using a for loop that starts when the Parcel Zip Code contains a value.

	if ( ZipCodes.size( ) > 0 ) {
	
		map <string, Load_u__c> validLZU = new map <string, Load_u__c> ( );
		//creates a map labeled validLZU with a key of string data type and a value in the Load Zone & Utilites object.
		
		for (Load_u__c obj : [SELECT Id, name, Load_Zone__C FROM Load_u__C WHERE name IN : ZipCodes] ) {
		//creates a for loop that queries the Load Zone & Utilities’ object records for the matching  zip code being stored in the ZipCodes set and returns the name and Load Zone fields.

			validLZU.put (obj.name, obj); 
			//loads the name (zip code) returned by the query into the key value of the validLZU map and loads the query as the map’s value.
		}
		
	for ( opportunity l : trigger.new) {

		if ( trigger.isInsert || trigger.oldMap.get(l.Id).ZipCode != l.Parcel_Zip__c && validLZU.containsKey (l.Parcel_Zip__c)) {
		// if the parcel zip code is inserted or if the parcel zip code is different than what it used to be and the map contains a name equal to the parcel zip code than execute:

			l.load_zone_utility_4__C = validLZU.get (l.Parcel_Zip__c).Load_Zone__C;
			//set the Load Zone & Utility field in the opportunity object to the corresponding Load Zone & utility field in the Load Zone & Utility object depending on the parcel zip code.
			
		}

		else if(trigger.oldMap.get(l.iD).Parcel_Zip__c != l.Parcel_Zip__c && !validLZU.containsKey(l.Parcel_Zip__c)) {
		// if the old parcel zip code is equal to the current parcel zip code and the map does not contain the parcel zip code execute:

			l. load_zone_utility_4__C __C = null;
			//set the Load Zone & Utility field in the opportunity object to null.
	}
}
}
}

My attempted test method is as follows:
 
@isTest
private class opportunityLZUTriggerTestClass {

Static testMethod void validateLZU(){

date myDate = date.newInstance(2016, 2, 17);
account myAccount = new account ();
//create myDate and myAccount variables to be inputted into the newOp opportunity.

opportunity newOp = new opportunity() ;
//create the newOp record in the opportunity object to play as a test record in the opportunity trigger.

newOp.name = ‘Newman Tower’;
newOp.account = myAccount;
newOp.type = 'New Business';
newOp.closeDate = myDate;
newOp.stageName = 'new';
newOp.parcel_zip__c = '02052';
newOp.Load_Zone_Utility_4__c = null;
//add values to the newOp record’s required fields. 
//because Load_Zone_Utility_4__c field is being auto-populated depending on the parcel zip code after the trigger, and is therfore currently blank, set to null.

test.startTest();
//start the test

insert newOp;
//insert the newly created record, newOp, into the opportunity object. 

test.stopTest();
//stop the test

Opportunity opQuery = [SELECT name, Load_Zone_Utility_4__c FROM opportunity WHERE name = ‘Newman Tower’];
//query the records in the opportunity object to return the name and Load Zone & Utility fields from the opportunity object where the name is equal to ‘Newman Tower’.
// set this query to the variable opQuery.

system.assertEquals('NEMA Eversource', opQuery.Load_Zone_Utility_4__c);
// Check that the Load Zone & Utility field in the query opQuery is equal to ‘NEMA Eversource’, which it should as the trigger’s job was to update this field based off of the zip code ‘02052’


}
}

The test is inputting the declared hypothetical data. Then the trigger is supposed to update the Load_Zone_Utility_4__C field based off of its Parcel_Zip__C of 02052. Therefore, originally the Load Zone field must be blank because it is dependent on the zip code - is null being used correctly to do this? 

If anybody can help, it would be greatly appreciated. 

Thank you.
 
Best Answer chosen by Nick Speyer
pconpcon
Here are some updates that I would make to both your trigger and your test.  For your test, line 09-16 are redundant and useless.  Also you never insert your newLZU.  The reason your test was failing with that error was because the newLZU was not inserted.  But it also exposed a problem in your trigger where you were checking the old map without seeing if you were in an update.  I changed that on line 32 of the trigger below

Trigger
Trigger updateLZU on Opportunity (before insert, before update) {
    Set<String> zipCodes = new Set<String>();

    for (opportunity opp : Trigger.new) {
        zipCodes.add(opp.Parcel_Zip__c);
    }

    zipCodes.remove(null);

    if (!zipCodes.isEmpty()) {
        Map<String, Load_u__c> validLZU = new Map<String, Load_u__c>();
     
        for (Load_u__c obj : [
            select Name,
                Load_Zone__c
            from Load_u__c 
            where name in :zipCodes
        ]) {
            validLZU.put(obj.name, obj);
        }

        for (Opportunity opp : Trigger.new) {
            if (
                (
                    Trigger.isInsert ||
                    Trigger.oldMap.get(opp.Id).Parcel_Zip__c != opp.Parcel_Zip__c
                ) && 
                validLZU.containsKey(opp.Parcel_Zip__c)
            ) {
                opp.Load_Zone_Utility_4__c = validLZU.get(l.Parcel_Zip__c).Load_Zone__C;
            } else if (
                Trigger.isUpdate &&
                Trigger.oldMap.get(opp.Id).Parcel_Zip__c != opp.Parcel_Zip__c &&
                !validLZU.containsKey(opp.Parcel_Zip__c)
            ) { 
                opp.Load_Zone_Utility_4__c = null;
            }
        }
    }
}

Test
@isTest
private class leadsLZUTriggerTestClass {
    static testMethod void validateLZUL(){
        Load_U newLZU = new Load_U(
            Name = '02052',
            Load_zone__c= 'NEMA Eversource'
        );
        insert newLZU;

        lead newLead = new Lead(
            FirstName = 'James',
            LastName = 'Sullivan',
            Company = 'Walmart',
            Status = 'contacted',
            Parcel_Zip__c = '02052'
        );

        Test.startTest();
     
        insert newLead;

        Database.leadConvert lc = new Database.leadConvert();
        lc.setLeadId(newLead.id);

        leadStatus convertStatus = [
            select MasterLabel
            from LeadStatus where IsConverted = true
            limit 1
        ];  

        lc.setConvertedStatus(convertStatus.MasterLabel);

        Database.LeadConvertResult lcr = Database.convertLead(lc);
        System.assert(lcr.isSuccess(), 'Lead should have converted');

        lc.setOpportunityName('James Sullivan');
     
        Test.stopTest();
     
        Opportunity opportunity = [
            select name,
                Load_Zone_Utility_4__c
            from opportunity
            where name = 'James Sullivan'
        ];  
     
        System.assertEquals('NEMA Eversource', opQuery.LZU__C, 'The LZU was not set correctly');
    }
}

 

All Answers

pconpcon
So it appears that your problem is that you are not creating a Load_u__c object.  All of your data has to be created for the tests.  So your test should be something like this:
 
@isTest
private class opportunityLZUTriggerTestClass {
    static testMethod void validateLZU(){
        Date myDate = Date.newInstance(2016, 2, 17);

        Load_u__c myLoad = new Load_u__c(
            Name = '02052',
            Load_Zone__c = 'NEMA Eversource'
        );
        insert myLoad;

        Account myAccount = new Account();

        Opportunity newOp = new Opportunity(
            name = 'Newman Tower',
            account = myAccount,
            type = 'New Business',
            closeDate = myDate,
            stageName = 'new',
            parcel_zip__c = '02052',
            Load_Zone_Utility_4__c = null
        );

        test.startTest();

        insert newOp;

        test.stopTest();

        Opportunity opQuery = [
            select name, Load_Zone_Utility_4__c
            from opportunity
            where name = 'Newman Tower'
        ];
        System.assertEquals(
            'NEMA Eversource',
            opQuery.Load_Zone_Utility_4__c,
            'The Load Zone Utiltity was not set correctly'
        );
    }
}

NOTE: This code has not been tested and may contain typographical or logical errors
Nick SpeyerNick Speyer
pcon, thank you for your response. That was exactly what I was looking for. I appreciate you taking the time to help me.

There is one final step in this process I am having trouble with. 

The opportunity test class is not gaining total code coverage because the opportunity is supposed to be created from a lead conversion - not created within the test class. This is because specific fields mapped from the lead object are populated in the opportunity object upon conversion. 

I now need to adjust this opportunity test class so that it creates a lead and converts it into an opportunity instead of creating both a lead and an opportunity.

I create a new lead and insert it into the test class. I then attempt to convert this lead using the LeadConvert class found here:
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_dml_convertLead.htm

I set the "newly created" opportunity's name to "James Sullivan" and aim to query the results to ensure the outcome.
 
@isTest
private class leadsLZUTriggerTestClass {

Static testMethod void validateLZUL(){

lead newLead = new lead(firstName = 'James', lastName = 'Sullivan', company = 'Walmart', status = 'contacted', Parcel_Zip__c = '02052') ;
Load_U newLZU = new Load_U ( name = '02052', Load_zone__c= 'NEMA Eversource');

newLead.FirstName = 'James';
newLead.LastName = 'Sullivan';
newLead.Company = 'Walmart';
newLead.Status = 'contacted';
newLead.Parcel_Zip__C = '02052';

newLZU.name = '02052';
newLZU.Load_Zone__c = 'NEMA Eversource';

test.startTest();
 
insert newLead;

database.leadConvert lc = new database.leadConvert();
lc.setLeadId(newLead.id);

leadStatus convertStatus = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true LIMIT 1];
lc.setConvertedStatus(convertStatus.MasterLabel);

Database.LeadConvertResult lcr = Database.convertLead(lc);
System.assert(lcr.isSuccess());

lc.setOpportunityName(‘James Sullivan’);
 
test.stopTest();
 
opportunity opQuery = [SELECT name, Load_Zone_Utility_4__c FROM opportunity WHERE name = ‘James Sullivan’];
 
system.assertEquals('NEMA Eversource', opQuery.LZU__C);
 
 
}
}

I am having trouble with the lead conversion class. I am receiving the following error message when running the test:

System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, updateLZUL: execution of BeforeInsert

caused by: System.NullPointerException: Attempt to de-reference a null object

Trigger.updateLZUL: line 25, column 1: []

Any ideas on how to solve this, or on how to reference a newly created opportunity from a lead conversion? 

 
pconpcon
Here are some updates that I would make to both your trigger and your test.  For your test, line 09-16 are redundant and useless.  Also you never insert your newLZU.  The reason your test was failing with that error was because the newLZU was not inserted.  But it also exposed a problem in your trigger where you were checking the old map without seeing if you were in an update.  I changed that on line 32 of the trigger below

Trigger
Trigger updateLZU on Opportunity (before insert, before update) {
    Set<String> zipCodes = new Set<String>();

    for (opportunity opp : Trigger.new) {
        zipCodes.add(opp.Parcel_Zip__c);
    }

    zipCodes.remove(null);

    if (!zipCodes.isEmpty()) {
        Map<String, Load_u__c> validLZU = new Map<String, Load_u__c>();
     
        for (Load_u__c obj : [
            select Name,
                Load_Zone__c
            from Load_u__c 
            where name in :zipCodes
        ]) {
            validLZU.put(obj.name, obj);
        }

        for (Opportunity opp : Trigger.new) {
            if (
                (
                    Trigger.isInsert ||
                    Trigger.oldMap.get(opp.Id).Parcel_Zip__c != opp.Parcel_Zip__c
                ) && 
                validLZU.containsKey(opp.Parcel_Zip__c)
            ) {
                opp.Load_Zone_Utility_4__c = validLZU.get(l.Parcel_Zip__c).Load_Zone__C;
            } else if (
                Trigger.isUpdate &&
                Trigger.oldMap.get(opp.Id).Parcel_Zip__c != opp.Parcel_Zip__c &&
                !validLZU.containsKey(opp.Parcel_Zip__c)
            ) { 
                opp.Load_Zone_Utility_4__c = null;
            }
        }
    }
}

Test
@isTest
private class leadsLZUTriggerTestClass {
    static testMethod void validateLZUL(){
        Load_U newLZU = new Load_U(
            Name = '02052',
            Load_zone__c= 'NEMA Eversource'
        );
        insert newLZU;

        lead newLead = new Lead(
            FirstName = 'James',
            LastName = 'Sullivan',
            Company = 'Walmart',
            Status = 'contacted',
            Parcel_Zip__c = '02052'
        );

        Test.startTest();
     
        insert newLead;

        Database.leadConvert lc = new Database.leadConvert();
        lc.setLeadId(newLead.id);

        leadStatus convertStatus = [
            select MasterLabel
            from LeadStatus where IsConverted = true
            limit 1
        ];  

        lc.setConvertedStatus(convertStatus.MasterLabel);

        Database.LeadConvertResult lcr = Database.convertLead(lc);
        System.assert(lcr.isSuccess(), 'Lead should have converted');

        lc.setOpportunityName('James Sullivan');
     
        Test.stopTest();
     
        Opportunity opportunity = [
            select name,
                Load_Zone_Utility_4__c
            from opportunity
            where name = 'James Sullivan'
        ];  
     
        System.assertEquals('NEMA Eversource', opQuery.LZU__C, 'The LZU was not set correctly');
    }
}

 
This was selected as the best answer
Nick SpeyerNick Speyer
Thank you pcon. Your changes helped a ton.