+ Start a Discussion
Steve SumnerSteve Sumner 

How to write a test class for a before insert trigger

Hi,
 
Can someone explain to me how to write a test class for an apex trigger like the following one ? This trigger assigns new Leads in Salesforce to the existing Account owner if the domain email address matches the Account's domain.

I'm new to writing Apex but it is working in the Sandbox. I just need a test class to be able to deploy it to Production.


Thanks 

 
trigger addAccount on Lead (before insert){

    //Use a set instead of a list to gather all of the unique domains
    Set<String> leadDomains = new Set<String>();

    //Loop through leads to populate the set
    for(Lead l : trigger.new){
        leadDomains.add(l.domain__c);
    }

    //Query for accounts
    List<Account> leadAccounts = [Select Id, OwnerId, domain__c From Account Where domain__c = :leadDomains];

    //Create Map and loop through list to populate the map
    Map<String,Account> accMap = new Map<String,Account>();
    for(Account a : leadAccounts){
        accMap.put(a.domain__c,a);
    }

    //Loop through leads and assign correct owner from Map
    for(Lead l2 : trigger.new){
        if(accMap.containsKey(l2.domain__c)){
            l2.OwnerId = accMap.get(l2.domain__c).OwnerId;
            l2.Existing_Account__c = true;
            
         
        }
        else{
           
        }
    }


}

 
Salesforce DeveloperSalesforce Developer
You can take reference from below code: 
@isTest
private class addAccountTriggerTest {
	
    @isTest
    private static void testTrigger(){
        test.startTest();
            Lead l = new Lead(FirstName = 'Test First Name', LastName = 'test Last Name', email = 'test@test.com', domain__c = 'Test', Company= 'Test Company');
            insert l;
        test.stopTest()
    }
	@testSetup
    private static void setupData(){
        Account a = new Account(Name = 'Test Account', Domain__c='Test');
        insert a;
        
    }
}


 
Rahul KumarRahul Kumar (Salesforce Developers) 
Hi Steve Sumner,
 
@isTest

public class addAccount
{
    static testMethod void testUnit()
	{
        
        Account zc = new Account ();
        zc.ownerId= '123456';
        zc.domain__c= 'evev' ;
		insert zc;
        
        Lead led = new Lead();
        led.lastname = 'Test';
        led.firstName ='Test';
        led.company = 'ABC';
        led.Zip_Code__c = '123456';
		// Add all required field
        insert led;
		
    }
}
Please check below post to learn about test classes
1)http://amitsalesforce.blogspot.com/2015/06/best-practice-for-test-classes-sample.html

Please follow below salesforce Best Practice for Test Classes:-

1. Test class must start with @isTest annotation if class version is more than 25
2. Test environment support @testVisible, @testSetUp as well
3. A unit test is to test a particular piece of code working properly or not.
4. Unit test method takes no argument, commit no data to the database, send no email, flagged with a testMethod keyword.
5. To deploy to production at-least 75% code coverage is required 
6. System.debug statement are not counted as a part of apex code limit.
7. Test method and test classes are not counted as a part of code limit
9. We should not focus on the percentage of code coverage ,we should make sure that every use case should cover including positive, negative, bulk and single record.
Single Action -To verify that the single record produces the correct and expected result.
Bulk action -Any apex record trigger, class or extension must be invoked for 1-200 records.
Positive behavior: Test every expected behavior occurs through every expected permutation, I,e user filled out every correct data and not go past the limit.
Negative Testcase:-Not to add future date, Not to specify a negative amount.
Restricted User:-Test whether a user with restricted access used in your code.
10. Test class should be annotated with @isTest.
11 . @isTest annotation with test method is equivalent to a test method keyword.
12. Test method should static and no void return type.
13. Test class and method default access are private, no matter to add access specifier.
14. classes with @isTest annotation can't be an interface or enum.
15. Test method code can't be invoked by nontest request.
16. Stating with Salesforce API 28.0 test method cannot reside inside nontest classes.
17. @Testvisible annotation to make visible private methods inside test classes.
18. The test method cannot be used to test web-service call out. Please use callout mock.
19. You can't  send email from the test method.
20.User, profile, organization, AsyncApexjob, Corntrigger, RecordType, ApexClass, ApexComponent ,ApexPage we can access without (seeAllData=true) .
21. SeeAllData=true will not work for API 23 version earlier.
22. Accessing static resource test records in test class e,g List<Account> accList=Test.loadData(Account,SobjectType,resource name').
23. Create TestFactory class with a @isTest annotation to exclude from organization code size limit.
24. @testSetup to create test records once in a method and use in every test method in the test class.
25. We can run a unit test by using Salesforce Standard UI,Force.com IDE , Console , API.
26. A maximum number of test classes run per 24 hours of a period is not greater of 500 or 10 multiplication of test classes of your organization.
27. As apex runs in system mode so the permission and record sharing is not taken into account. So we need to use a system.runAs to enforce record sharing.
28. System.runAs will not enforce user permission or field level permission.
29. Every test to runs count against the total number of DML issued in the process.

Please let us know if this post will help you.

Please mark it as best answer if the information is informative.so that question is removed from an unanswered question and appear as a proper solution.

Thanks
Rahul Kumar

 
Steve SumnerSteve Sumner

Thank you, Rahul.

This information is most helpful...I will study it and do a lot more practice with triggers and classes.

I was able to create and save the class, but when I try to deploy both the trigger and the class to Production, I'm still getting 0% code coverage. Do I need to incorporate the class into my trigger somehow, or is there something else I need to be doing in the Sandbox before creating the change set ?

I appreciate your patience and your assistance.

Steve

Steve SumnerSteve Sumner
This is the error I'm getting for the Class when I run a Test in the Sandbox:


Pass/FailFail
Error MessageSystem.StringException: Invalid id: 123456
Stack TraceClass.addAccount.testUnit: line 13, column 1
Salesforce DeveloperSalesforce Developer
The account’s owner Id is incorrect. Id should be 15 or 18 digit and follow the format. 123456 isn’t correct id. Comment the below line :
zc.ownerId = ‘123456’;

and try.