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
StephenDicksonStephenDickson 

Help with test class on a Contact trigger

I created a trigger to update a custom field (Mailing County) before insert of a Contact.  The trigger takes the MailingPostalCode entered by the user and finds the County in which that zip code is found.  This is done via a custom object (Zip_Code__c) in which the Postal Codes are stored along with their respective Counties.

I would love any feedback on how to make this trigger better, but specifically I am confused because one of my test methods is not working (TestContactWithValidZip).  This particular test gets caught by my addError clause of my trigger.

Trigger:
trigger CountyLookupByZip on Contact (before insert) {
    for (Contact c : Trigger.New) {
        if(c.MailingPostalCode != null) {
        	List<Zip_Code__c> contactCounty = new List<Zip_Code__c>();
            contactCounty = [SELECT Id,
                                County__c,
                                Postal_Code__c
         				 FROM   Zip_Code__c 
        			     WHERE  Postal_Code__c = :c.MailingPostalCode];
            if(contactCounty.size() != 0){
            	c.Mailing_County__c = contactCounty[0].County__c;
            } else {
                c.MailingPostalCode.addError('Postal Code not found. Please ensure the postal code is a valid Virginia zip code.');
            }
        }
	}
}
Test Clas:
@isTest
public class TestCountyLookupByZip {

    @isTest
    public static void TestContactWithNullZip() {
        // Test data setup
        // Create a contact without a Mailing Postal Code
        // and check to ensure County is also null
        Contact contactNullZip = new Contact(LastName = 'Test');
        insert contactNullZip;
        
        // Perform Test
        System.assertEquals(contactNullZip.Mailing_County__c, null);
    }

    @isTest
    public static void TestContactWithValidZip() {

        // Test data setup
        // Create a contact with a valid VA Mailing Postal Code
        // and check to ensure County is updated correctly
        
    	Contact contactValidZip = new Contact(LastName = 'Test', MailingPostalCode = '20101');
        insert contactValidZip;
        
        // Perform Test
        System.assertEquals(contactValidZip.Mailing_County__c, 'Loudoun');
    }   
    
    @isTest
    public static void TestContactWithInvalidZip() {
        // Test data setup
        // Create a contact with an invalid Mailing Postal Code
        // and throw an error
        Test.startTest();
        try {
       		Contact contactInvalidZip = new Contact(LastName = 'Test', MailingPostalCode = '17602');
        	insert contactInvalidZip;
        // Perform Test
        } catch(Exception e) {
			System.Assert(e.getMessage().contains('FIELD_CUSTOM_VALIDATION_EXCEPTION'));
            System.Assert(e.getMessage().contains('Postal Code not found. Please ensure the postal code is a valid Virginia zip code.'));
        }
        Test.stopTest();
    }
}


 
Best Answer chosen by StephenDickson
Andrew GAndrew G
Hi Stephen
You still get the error as you have not re-queried the record that you have created.  
If you go to this thread  https://developer.salesforce.com/forums/ForumsMain?id=9062I000000IKZFQA4
and search for "why we grab the written record in our Apex Test Classes" you will see a post that will explain what is required and why.

But if you want the short version, update your method to:
@isTest
    public static void TestContactWithValidZip() {

        // Test data setup
        // Create a contact with a valid VA Mailing Postal Code
        // and check to ensure County is updated correctly
        Zip_Code__c zipCode = new Zip_Code__c(Postal_Code__c = '20101', County__c = 'Loudoun');
        insert zipCode;
        
    	Contact contactValidZip = new Contact(LastName = 'Test', MailingPostalCode = '20101');
        insert contactValidZip;
        Contact insertedContact = [SELECT Id, Mailing_County__c FROM Contact WHERE Id = :contactValidZip.Id  LIMIT 1];
        
        // Perform Test
        //general format for asserts is expected v actual so 
        System.assertEquals('Loudoun', insertedContact.Mailing_County__c, );
    }

Regards
Andrew

All Answers

SRKSRK

you can just cretea a apex calss 

public class MyJSONResponce {

    public List<Overalldata> overalldata;

    public class Overalldata {
        public String stateName;
        public String rating;
        public String active;
        public String Capital;
    }

    
    public static JSON2Apex parse(String json) {
        return (MyJSONResponce) System.JSON.deserialize(json, MyJSONResponce.class);
    }
}

MyJSONResponce  obj = new MyJSONResponce();

obj = MyJSONResponce.parse(<Your JSON String>);

for(MyJSONResponce.overalldata obj : obj.overalldata)
{
string fieltext = obj.stateName;
fieltext += obj.rating;
fieltext += obj.active;
fieltext += obj.Capital;
}

Puru GangwarPuru Gangwar
Please insert valid test data in Zip_Code__C class

    @isTest
    public static void TestContactWithValidZip() {

        // Test data setup
        // Create a contact with a valid VA Mailing Postal Code
        // and check to ensure County is updated correctly
        // 
        Zip_Code__c zipCode = new Zip_Code__c(Postal_Code__c= '20101', County__c= 'ABC');
        insert zipCode;
        Contact contactValidZip = new Contact(LastName = 'Test', MailingPostalCode = '20101');
        insert contactValidZip;
        
        // Perform Test
        System.assertEquals(contactValidZip.Mailing_County__c, 'Loudoun');
    }   

You need bulkified the code. As a best practice we should not call SOQL inside for loop as it will cross the governance limit.
Puru GangwarPuru Gangwar
Updated type and code.

Please insert valid test data in Zip_Code__C object in your test mehod

    @isTest
    public static void TestContactWithValidZip() {

        // Test data setup
        // Create a contact with a valid VA Mailing Postal Code
        // and check to ensure County is updated correctly
        // 
        Zip_Code__c zipCode = new Zip_Code__c(Postal_Code__c= '20101', County__c= 'Loudoun');
        insert zipCode;
        Contact contactValidZip = new Contact(LastName = 'Test', MailingPostalCode = '20101');
        insert contactValidZip;
        
        // Perform Test
        System.assertEquals(contactValidZip.Mailing_County__c, 'Loudoun');
    }   

You need to bulkified the code. As a best practice, we should not call SOQL inside for loop as apex trigger may throw governance limit error in case more than 100 records.
StephenDicksonStephenDickson
Puru,

Thank you for your reply.  I forgot that the Test Class does not "see" any of the data in the org and therefore we have to create all data needed for the test.  I updated the test method (TestContactWithValidZip), however now I am getting the following error message: 'System.AssertException: Assertion Failed: Expected: null, Actual: Loudoun'.

In the custom object, Zip_Code__c, the field Postal_Code__C is unique and so there should always be only one record returned in my SOQL query.  Does that still need to be bulified?  If I take that SOQL outside of the for loop, how would I reference the MailingPostalCode entered in Trigger.new?
 
trigger CountyLookupByZip on Contact (before insert) {
    for (Contact c : Trigger.New) {
        if(c.MailingPostalCode != null) {
        	List<Zip_Code__c> contactCounty  = [SELECT Id,
                                County__c,
                                Postal_Code__c
         				 FROM   Zip_Code__c 
        			     WHERE  Postal_Code__c = :c.MailingPostalCode];
            if(contactCounty.size() != 0){
            	c.Mailing_County__c = contactCounty[0].County__c;
            } else {
                c.MailingPostalCode.addError('Postal Code not found. Please ensure the postal code is a valid Virginia zip code.');
            }
        }
	}
}
 
@isTest
public class TestCountyLookupByZip {

    @isTest
    public static void TestContactWithNullZip() {
        // Test data setup
        // Create a contact without a Mailing Postal Code
        // and check to ensure County is also null
        Contact contactNullZip = new Contact(LastName = 'Test');
        insert contactNullZip;
        
        // Perform Test
        System.assertEquals(contactNullZip.Mailing_County__c, null);
    }

    @isTest
    public static void TestContactWithValidZip() {

        // Test data setup
        // Create a contact with a valid VA Mailing Postal Code
        // and check to ensure County is updated correctly
        Zip_Code__c zipCode = new Zip_Code__c(Postal_Code__c = '20101', County__c = 'Loudoun');
        insert zipCode;
        
    	Contact contactValidZip = new Contact(LastName = 'Test', MailingPostalCode = '20101');
        insert contactValidZip;
        
        // Perform Test
        System.assertEquals(contactValidZip.Mailing_County__c, 'Loudoun');
    }   
    
    @isTest
    public static void TestContactWithInvalidZip() {
        // Test data setup
        // Create a contact with an invalid Mailing Postal Code
        // and throw an error
        Test.startTest();
        try {
       		Contact contactInvalidZip = new Contact(LastName = 'Test', MailingPostalCode = '17602');
        	insert contactInvalidZip;
        // Perform Test
        } catch(Exception e) {
			System.Assert(e.getMessage().contains('FIELD_CUSTOM_VALIDATION_EXCEPTION'));
            System.Assert(e.getMessage().contains('Postal Code not found. Please ensure the postal code is a valid Virginia zip code.'));
        }
        Test.stopTest();
    }
}


 
Andrew GAndrew G
Hi Stephen
You still get the error as you have not re-queried the record that you have created.  
If you go to this thread  https://developer.salesforce.com/forums/ForumsMain?id=9062I000000IKZFQA4
and search for "why we grab the written record in our Apex Test Classes" you will see a post that will explain what is required and why.

But if you want the short version, update your method to:
@isTest
    public static void TestContactWithValidZip() {

        // Test data setup
        // Create a contact with a valid VA Mailing Postal Code
        // and check to ensure County is updated correctly
        Zip_Code__c zipCode = new Zip_Code__c(Postal_Code__c = '20101', County__c = 'Loudoun');
        insert zipCode;
        
    	Contact contactValidZip = new Contact(LastName = 'Test', MailingPostalCode = '20101');
        insert contactValidZip;
        Contact insertedContact = [SELECT Id, Mailing_County__c FROM Contact WHERE Id = :contactValidZip.Id  LIMIT 1];
        
        // Perform Test
        //general format for asserts is expected v actual so 
        System.assertEquals('Loudoun', insertedContact.Mailing_County__c, );
    }

Regards
Andrew
This was selected as the best answer
StephenDicksonStephenDickson
Brilliant.  Thanks, Andrew!  I knew I was missing something in regards to how the method was handling the test data.  Thanks for giving me that resource so I can go deeper into the subject. 

Cheers,
Stephen