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
Meghana SharmaMeghana Sharma 

How to resolve "FIELD_CUSTOM_VALIDATION_EXCEPTION" in the test class

Hello 

i have written a test class for the trigger, when i try to run the test i get 100% code coverage,i have even disabled the validation rule which is present on the lead object,  but still in the Test results i get the following error

System.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, Error::::::Divide by 0: [CRM_Owner__c]

how do i resolve this issue
Below is my trigger and Test class
 
trigger ShareWithCRMOwner on Lead (after insert,after update) {
    List<LeadShare> csShareList = new List<LeadShare>();
    for( Lead cs : trigger.new ) {
        if( cs.CRM_Owner__c != NULL ) {
            // Create a new LeadShare object for each Lead where CRM_Owner__c field is not NULL.
            LeadShare csShare = new LeadShare();
            // Give Read write access to that user for this particular Lead record.
            csShare.LeadAccessLevel = 'edit';
            // Assign Lead Id of Lead record.
            csShare.LeadId = cs.id;
            // Assign user id to grant read write access to this particular Lead record.
            csShare.UserOrGroupId = cs.CRM_Owner__c;
            csShareList.add( csShare );
        }
    }
    if( csShareList != null && csShareList.size() != 0 ) {
        try {
            insert csShareList;
            update csShareList;
             if(Test.isRunningTest())
            {
                integer k=1/0;
            }
        }catch( Exception e ) {
            trigger.new[0].CRM_Owner__c.addError('Error::::::'+e.getMessage());
        }
    }
}

Test Class
 
@isTest
private class TestShareWithCRMOwner {
    
    // test that newly inserted records marked as pubic=true have corresponding shares created
    static testMethod void testAddShares() {
        
        Set<ID> ids = new Set<ID>();
        List<Lead> Leads = new List<Lead>();
        
        for (Integer i=0;i<50;i++)
            Leads.add(new Lead(FirstName='First ',LastName='Name '+i,RecordTypeId='012p0000000Nn05AAC',
                               Email='email'+i+'@email.com',Company='ABSYZ',CRM_Owner__c='00528000006OKhPAAW'));
        
        insert Leads;
        
        // get a set of all new created ids
        for (Lead c : Leads)
            ids.add(c.id);
        
        // assert that 50 shares were created
        List<LeadShare> shares = [select id from LeadShare where 
                                  LeadId IN :ids and RowCause = 'Manual'];
        System.assertEquals(shares.size(),50);
        
    }
    
    // insert records and switch them from public = true to public = false
    static testMethod void testUpdateContacts() {
        
        Set<ID> ids = new Set<ID>();
        List<Lead> Leads = new List<Lead>();
        
        for (Integer i=0;i<50;i++)
            Leads.add(new Lead(FirstName='First ',LastName='Name '+i,RecordTypeId='012p0000000Nn05AAC',
                               Email='email'+i+'@email.com',Company='ABSYZ',CRM_Owner__c='00528000006OKhPAAW'));
        
        insert Leads;
        
        for (Lead c : Leads)
            ids.add(c.id);
        
        update Leads;
        
        // assert that 0 shares exist
        List<LeadShare> shares = [select id from LeadShare where 
                                  LeadId IN :ids and RowCause = 'Manual'];
        System.assertEquals(shares.size(),0);
        
        for (Lead c : Leads)
            c.CRM_Owner__c='2F00528000006OKhP';
        
        update Leads;
        
        // assert that 50 shares were created
        shares = [select id from LeadShare where LeadId IN :ids and RowCause = 'Manual'];
        System.assertEquals(shares.size(),50);
        
        for (Lead c : Leads)
            c.CRM_Owner__c='2F00528000006OKhP';
        
        update Leads;
        
        // assert that 0 shares exist
        shares = [select id from LeadShare where LeadId IN :ids and RowCause = 'Manual'];
        System.assertEquals(shares.size(),0);
        
    }
    
}




 
SarvaniSarvani
Hi Meghana,

Try changing ur code to some value other than dividing 1/0 in line 22 of your trigger, something like below
if(Test.isRunningTest())

            {
                integer k=1;
            }

Hope this helps!

Thanks
 
Meghana SharmaMeghana Sharma
@sarvani
i tried to change the code but now i get the new error " System.AssertException: Assertion Failed: Expected: 50, Actual: 0"
SarvaniSarvani
Hey Meghana, The test class is expecting to find 50 records and is not finding any, so displaying actual as 0.  You can add system.debug() statements to your code and review the debug log to find out why the records are not being created/updated.

Thanks
Meghana SharmaMeghana Sharma
@Sarvani
i am new to the apex development, can you show me a sample of putting system.debug() statements
SarvaniSarvani
As you are inerting the list csShareList in your trigger see how many records are actually inserted. For example, use the line below on your code :
System.debug('size of my list is: ' +csShareList.size());
In the same way, print your size in test class as its giving error expected 50 but actual 0:
System.debug('Size of records inereted or updated is: '+shares.size());
After executing select debug the only checkbox in the bottom panel, which will show you the size of records that you are trying to insert or update.

​​​​​​​Thanks
 
Meghana SharmaMeghana Sharma
@Sarvani

the debug log says records are getting inserted, i am not sure where am i going wrong

User-added image
Leanbridge TechnologiesLeanbridge Technologies
Not a complete fix and probably not best practice, but I've had similar issues where my tests hit the validation rules and therefore fail.
If you absolutely need to get it deployed and don't have time to write your test with runAs(), you could deactivate the validation rule on both source and target environments, make your deployment, then reactivate the validation rules. This would allow the Tests to pass as there are no validation rules to prevent them from passing.
Again, probably not best practice, but it lets you make your deployment.
carl mithcarl mith
Thanks for the post and nice to see this here. Get more about the best apps here to use. https://www.turnpdf.com
Puneet_MishraPuneet_Mishra
Hi Meghana,

Looking at your code, it looks like you are trying to achieve 100% code coverage and wanted to include catch block as well that's is why you are trying to divide 1/0. 

one question before I post the code
- Why are you inserting the leadshare records and immediately updating it, what are you trying to achieve here? If not required remove the update statement.

Coming to your test class there is a way you can cover your test coverage, you can throw a custom exception and add a try-catch block in your test class where you can put an assert statement to verify the exception thrown.

1. Create a custom exception class extending Exception
public class CustomException extends Exception {

}

2. Update your trigger with below code, we are throwing custom exception when running in test context.
trigger ShareWithCRMOwner on Lead (after insert,after update) {
    List<LeadShare> csShareList = new List<LeadShare>();
    for( Lead cs : trigger.new ) {
        if( cs.CRM_Owner__c != NULL ) {
            // Create a new LeadShare object for each Lead where CRM_Owner__c field is not NULL.
            LeadShare csShare = new LeadShare();
            // Give Read write access to that user for this particular Lead record.
            csShare.LeadAccessLevel = 'edit';
            // Assign Lead Id of Lead record.
            csShare.LeadId = cs.id;
            // Assign user id to grant read write access to this particular Lead record.
            csShare.UserOrGroupId = cs.CRM_Owner__c;
            csShareList.add( csShare );
        }
    }
    
    try {
        if( csShareList != null && csShareList.size() != 0 ) {
            insert csShareList;
            update csShareList;
        } else { // this else block will run when test class create lead records but CRM_Owner__c field are null, which will throw custom exception
            if(Test.isRunningTest()) {
                throw new CustomException('Exception thrown for test class');
            }
        }
    } catch (Exception e) {
        trigger.new[0].CRM_Owner__c.addError('Error::::::'+e.getMessage() + ' == ' + e.getLineNumber());
    }
}
moved try-catch block above if condition and throwing a custom exception for test class context when csShareList is empty.

3. Update your test class with below code:
@isTest
private class TestShareWithCRMOwner {
    
    // test that newly inserted records marked as pubic=true have corresponding shares created
    static testMethod void testAddShares() {
        
        Set<ID> ids = new Set<ID>();
        List<Lead> Leads = new List<Lead>();
        
        for (Integer i=0;i<50;i++)
            Leads.add(new Lead(FirstName='First ',LastName='Name '+i,
                               Email='email'+i+'@email.com',Company='ABSYZ',CRM_Owner__c='0050I000009tQuH'));
        
        insert Leads;
        
        // get a set of all new created ids
        for (Lead c : Leads)
            ids.add(c.id);
        
        // assert that 50 shares were created
        List<LeadShare> shares = [select id from LeadShare where 
                                  LeadId IN :ids and RowCause = 'Manual'];
        System.assertEquals(shares.size(),50);
        
    }
    
    static testMethod void testException() {
        
        Set<ID> ids = new Set<ID>();
        List<Lead> Leads = new List<Lead>();
        Boolean isException = false;
        
        for (Integer i=0;i<50;i++)
            Leads.add(new Lead(FirstName='First ',LastName='Name '+i, Email='email'+i+'@email.com',Company='ABSYZ'));
        
        try {
            insert Leads;
        } catch(Exception e) {
            if(e.getMessage().contains('Exception thrown for test class'))
            isException = true;
            system.assertEquals(isException, true);
        }
        
        for (Lead c : Leads)
            ids.add(c.id);
       
        // assert that 50 shares were created
        List<LeadShare> shares  = [select id from LeadShare where LeadId IN :ids and RowCause = 'Manual'];
        System.assertEquals(shares.size(),0);
    }
    
}
declare isException attribute for exception check thrown from trigger and doing DML on lead records inside try-catch block, catching custom exception and validating using system. assert statement.

I hope it will help.

Regards,
Puneet.