+ Start a Discussion
Sara Massey 10Sara Massey 10 

I am trying to write my first Apex test class. Is there any simple step by step resource as to how to get started? I have a few very small Apex classes that I created in our Sandbox that

compile fine, but now I am ready to move them to production.  I have been researching the basics of writing test classes, but it definitely seems a bit overwhelming in terms of where to begin, etc.  as an example, If i have an apex class (e2), and I am writing a unit Test class for this class, would the name of the test class be public class e2Test (after the @istest keyword)? when i run a test class through the developer console and choose the test class (e2Test) how does it get associated with the actual class e2??  
ANUTEJANUTEJ (Salesforce Developers) 
Hi Sara,

You would be associating the class with the test class by calling that particular class methods by instantiating the class and calling the methods thereby executing the methods of the classes.

Generally as you mentioned writing test after the classname you are testing makes it clear in case if others are working on that particular class to extend the functionality.

I hope this helped.

Regards,
Anutej
Cloud Expert's SupportCloud Expert's Support

Hey Sara,

Every test class begins with @istest keyword if you want to write the test class for your apex class you need to first check out the associate lookup on the page and create an instance of all those lookups and pass the mandatory value. Next step is check whether it is standard or controller class you have used you need to pass the value according to that. Code coverage must be more than 75%. 

 

Apex code:
public class Invoice_PDF {
  public Invoice__c po{get;set;}
  public list<Invoice_Line_Item__c> poli{get;set;}
  public decimal totQuantity{get;set;}
  public decimal totAssessable {get;set;}
  public decimal igst18{get;set;}
  public decimal total_Amount_with_tax{get;set;}
    public Invoice_PDF(ApexPages.StandardController controller) 
    {
     id recid = ApexPages.currentPage().getParameters().get('id');
     system.debug(recid);
     totQuantity = 0;
     totAssessable =0;
     igst18=0;
     total_Amount_with_tax=0;
    
     po=[SELECT Id, Name, CreatedById, Sales_Order__c, Mode_of_Dispatch__c, Vehicle_No__c, Receiving_Station__c, Payment_Due_on__c, Bill_To__c, 
     Ship_To__c, PO_Number__c, PO_Date__c, E_Way_Bill_No__c, Date_Time_of_Preparation__c, Date_Time_of_Removal__c, CGST_9__c, SGST_9__c, IGST_18__c, 
     Total_Invoice_Value__c, Account__c, Cost_Centre__c,Bill_To__r.Name,Bill_To__r.city__c,Bill_To__r.Street__c,Bill_To__r.Country__c,Bill_To__r.State__c,
     Ship_To__r.Name,Ship_To__r.city__c,Ship_To__r.Street__c,Ship_To__r.Country__c,Ship_To__r.State__c   
     FROM Invoice__c WHERE id=:recid];
     
     poli=[SELECT Id,Invoice__c, Sales_Order__c, SO_Line_Item__c, Product_Master__c, Quantity__c, Quantity_in_Kgs__c, UOM__c, Rate__c, 
     Total_Assessable_Value__c, HSN_Code__c, CGST_9__c, SGST_9__c, IGST_18__c, Product_Description__c, Object_Age__c, WO_Line_Item__c, 
     Sale_Item_Master__c,Sale_Item_Master__r.name,Sale_Item_Master__r.Length_Mtrs_WB_SD_Coil__c FROM Invoice_Line_Item__c where Invoice__c=:po.id];
     
     
 
 }
}

TEST CLASS:
@istest
public class Invoice_PDF_Test 
{
public static testmethod void test()
{
    insert new Auto_Number__c(Name='IN',Auto_Number__c='1'); 
   
    Invoice__c inv=new Invoice__c();
    inv.Name='123';
    insert inv;
    
    PageReference pr = Page.InvoicePDF;
    Test.setCurrentPage(pr);
    ApexPages.StandardController pp= new ApexPages.StandardController(inv); 
    pr.getParameters().put('id',String.valueOf(inv.id));
    Invoice_PDF ip=new Invoice_PDF(pp);
    
}
}

Sara Massey 10Sara Massey 10
Thank you both for the information.  It is defniitely helpful and useful.  I wanted to ask if Test classes are created any differently if they contain SOQL queries within them?  I am starting to get the concept behind the test classes and how to test each method with bulk, single negative, positive datapoints, etc. But I am having trouble applying the concept when the code includes SOQL queries.  I came across this particular command today and it seemed that it would be something to use in the scenario where I am querying the database with SOQL: Test.setFixedSearchResults()  Just wondering if that Is correct? 
Sanjay Bhati 95Sanjay Bhati 95
Hi Sara,

Please have a look on below detail.

The test class is used to write the unit test for our code. Here is basic example of test class.
 
@isTest
public class asPerYourSuggestion{
       @TestSetup // Not required, Use only to insert the records that we need in out apex class.
        public static void methodName(){
             // Here you will insert all the type of records that is used in your apex controller. Data of your record should contain the same value as you checking in apex class.
             // Ex: Somewhere you are using account then you have to insert a record of account.
            // If you have if and else part in your code then you have to insert two account records so One records will fulfill the If condition 
                and second, will fulfill the else part.
        }

       @isTest
       public static void test1(){
             // Here you will call the method created in apex class.
            // Suppose you have a method that need parameter of any id of record or something else.
            // You can query the needed record here and get the id of particular record. This query will return only the record created in above setup method.
           // Ex: Account acc = [Select Id From Account Limit 1];
           // ControllerName.MethodName(acc.Id);
       }
}

Let me know if you have any doubt.
Sara Massey 10Sara Massey 10
Sanjay - 
thank you so much.  Yes, this helps quite a bit.  Keeps it simple while still clearly explaining the concept.  I do have a question related to the types of records in the controller class.  I have an apex class that I am using for a visualforce page.  The standardcontroller on the VF page is (Project_Budget__c).  This is a detail object for the master Object (Project__c).  In my Apex Class, I have a constructor for the Project_Budget__c.  For the test class, would I need to create a Project Record AND a Project Budget Record?  I also have a couple of PageReference Methods.  Will I need to create these in my test class as well?  Is there an example you might have of how to create a test class instance of a PageReference 'record'?    thanks again for all of your assistance! Sara
Sanjay Bhati 95Sanjay Bhati 95
Hi Sara,
 
//If you are inserting any record then you have to check is there any master-detail relationship object. If object have master then you have to insert it.
// Also you have to fill all the fields that are required to create a record.

Projet__c project = new Project();
//Insert project.

Project_Budget__c pb = new Project_Budget__c();
pb.Project__c = project.Id;
// Insert project record


ApexPages.StandardController sc = new ApexPages.StandardController(pb);
yourControllerName testAccPlan = new yourControllerName(sc);
        
PageReference pageRef = Page.Your Page Name;
//Optional if you are getting parameter
pageRef.getParameters().put('id', String.valueOf(pb.Id)); 

Test.setCurrentPage(pageRef);
// This will conver your standard controller constructor.

Thanks, Let me know if you have any doubt.
Sara Massey 10Sara Massey 10
Sanjay - 
thanks again so much for your assistance.  I am still having trouble getting my first Test Class working.  Below is the Apex Class and the Test Class that I am attempting to create.  Any input would be very much appreciated.  

 
public class initbud5{
    
    public Project_Budget__c budget {get;set;}

    public initbud5(ApexPages.StandardController stdController){
             this.budget = (Project_Budget__c)stdController.getRecord();            
             system.debug(budget);
    }       
     public pageReference wasfinalized(){      
         update budget;
         pageReference prs = new pageReference('/' + budget.Project__c);
         prs.setRedirect(true);
         return prs;    
    }
    public pageReference save(){  
         budget.Budget_Approved__c =TRUE;
         update budget;
         pageReference readOnly = new pageReference('/' + budget.Project__c);
         readOnly.setRedirect(true);
         return readOnly;   
    }   
}
 
@isTest
public class initbud5Test {       
        
     @testsetup
    public static void initbud5testmethod(){
                     
        Account acct = new Account(Name='Name');
        insert acct;
        Project__c proj = new Project__c(Name='projName');
        proj.Account__c = acct.Id;
        insert proj;
        Project_Budget__c projBud = new Project_Budget__c(Name='projBudName', Project__c=proj.Id);                   
        insert projBud; 
           
            PageReference pr = Page.InitialBudgetLayoutedit;
            Test.setCurrentPageReference(pr);
            ApexPages.StandardController sc = new ApexPages.StandardController(projBud);
            pr.getParameters().put('id',String.valueOf(projBud.id));

     }
    @isTest
    public static void wasfinalized(){
         Project_Budget__c projBud = [SELECT Id, Name FROM Project_Budget__c LIMIT 1];
         Boolean ba = projBud.Budget_Approved__c;
         System.assertEquals(True,ba, 'message');
    }
    
    
    
    
    
}

 
Sara Massey 10Sara Massey 10
thx everyone for the information. It is all definitely very helpful.  I have been studying more information regarding creating Test Classes, and I do see that there are many resources provided to become proficient at writing test classes (in my particular case currently - unit tests).  Any feedback based on my code above is definitley welcome, but in the meantime - it might make sense for me to continue to learn more about the process, etc. so that when I do have questions I can communicate them better. :) 
I found a unit testing trail in trailhead - so I will most definitley complete this as well.