How to prepare Test Data for your Test Classes? – Part 2

Hello Everyone,

I am back yet again.

This is a continuation of my previous post How to prepare Test Data for your Test Classes? – Part 2, where we saw how to create test data for your test classes. Today we will try to implement the same in a real-time scenario. Like I said, let’s get into some action.

Scenario

We are going to create a visualforce page, which will have an account lookup field to search account. Once selected, we should be able to show related contacts in a table. Simple isn’t it? Now let’s see how we have written the code for the page and the controller.

Visualforce Page

Create a simple VF page where we have a lookup field to select Account and a Search button. On click on the button, the related contacts must be displayed below the page. You may also add another button called Clear to refresh the page.

<apex:page controller="AccountSearchController">
    <apex:form >
    <apex:pageBlock title="Search Account">
            <apex:inputField value="{!account.ParentId}" />
            <apex:pageBlockButtons location="bottom">
            <apex:commandButton action="{!searchContacts}" value="Search"
                reRender="contactResults"/>
                <apex:commandButton action="{!clear}" value="Clear"/>
            </apex:pageBlockButtons>
        </apex:pageBlock>
        <apex:outputPanel Id="contactResults">
            <apex:pageBlock rendered="{!contacts != NULL }">
                <apex:pageBlockTable value="{!contacts}" var="c" >
                    <apex:column value="{!c.Name}"/>
                </apex:pageBlockTable>
            </apex:pageBlock>
        </apex:outputPanel>
    </apex:form>
</apex:page>

 

Apex Controller

Below custom controller contains all related methods to run the page.

public class AccountSearchController {
 //variables
 public Account account{get;set;}
 public List<Contact> contacts{get;set;}

 //constructor
 public AccountSearchController() {
  account = new Account();
 }

 //return account
 public Account getAccount() {
  return account;
 }

 //search contacts
 public void searchContacts() {
  contacts = new List<Contact>();
  contacts = [SELECT Id,Name FROM Contact WHERE AccountId = :account.ParentId];
 }

 //return list of contacts
 public List<Contact> getContacts(){
  return contacts;
 }

 //to clear the page
 public PageReference clear() {
  PageReference pg = Page.AccountSearchPage;
  pg.setRedirect(true);
  return pg;
 }
}

Test Utility Class

Now below class is going to serve as a test utility class for our org. The class should be annotated by @isTest to ensure that we exclude the class from the organization code size limit and execute in test context only. This means that the methods mentioned in this class can only be called from a test class.

Now if you see below, we have methods to create accounts and contacts. The method accepts an integer field as a parameter to decide the number of records to be created. By this, we are making the methods more reusable in other contexts.

@isTest
public class TestUtilityClass {

 //method to create accounts.
 //Parameter numAccts decides the no. of records to be created.
 public static List<Account> createAccounts(Integer numAccts) {
  List<Account> accts = new List<Account>();
  for(Integer i=0; i<numAccts; i++) {
   accts.add(new Account(Name = 'TestAccount' + (i+1)));
  }
  return accts;
 }

 //method to create contacts
 //Paramter acc accepts account.
 //Parameter numConts decides the no. of contacts to be created.
 public static List<Contact> createContacts(Account acc, Integer numConts) {
  List<Contact> conts = new List<Contact>();
  for(Integer i=0; i<numConts; i++) {
   conts.add(new Contact(FirstName = 'Test', LastName = 'Contact' + i+1, AccountId = acc.Id));
  }
  return conts;
 }

}

Test Class

Here comes our test class. The class will ensure that the code coverage for AccountSearchController class is 100%.

Now the test class must be annotated with @isTest. The first method in the class would be our test data setup method. The method starts with @testSetup annotation as shown below:

//method to setup test data
@testSetup static void setup() {
 //invoke method from testUtilityClass to create account
 List<Account> accounts = TestUtilityClass.createAccounts(1);
 insert accounts;

 //invoke method from testUtilityClass to create contacts
 List<Contact> contacts = TestUtilityClass.createContacts(accounts[0], 2);
 insert contacts;
}

Now if you see closely, we are calling respective methods to create an account and related 2 contacts from the class TestUtilityClass. The results will be passed to respective list variables and then inserted. Thus, we have prepared the test data that is required for the test class to run.

Now, we will write our test method as shown below. We have declared the method as testMethod here. Alternately you can also annotate the method with @isTest and not mention testMethod.

//test method
 static testMethod void myUnitTest(){
  //query account which is prepared at test setup method
  Account acc = [SELECT Id,ParentId,Name FROM Account
                WHERE Name = 'TestAccount1'];

  //start test
  Test.startTest();
  PageReference pg = Page.AccountSearchPage;
  Test.setCurrentPageReference(pg);
  AccountSearchController controller = new AccountSearchController();
  controller.getAccount();
  controller.account = acc;
  //search contacts which were created at test setup method
  controller.searchContacts();
  controller.getContacts();
  controller.clear();
  Test.stopTest();
  //end test
 }

At first, we are querying the account that we created in the setup method. We will be passing the account as value to our controller of AccountSearchController class.

The final test class must be written as below:

@isTest
public class AccountSearchControllerTest {
 //method to setup test data
 @testSetup static void setup() {
  List<Account> accounts = TestUtilityClass.createAccounts(1);
  //invoke method from testUtilityClass to create account
  insert accounts;

  List<Contact> contacts = TestUtilityClass.createContacts(accounts[0], 2);
  //invoke method from testUtilityClass to create contacts
  insert contacts;
 }

 //test method
 static testMethod void myUnitTest(){
  //query account which is prepared at test setup method
  Account acc = [SELECT Id,ParentId,Name FROM Account
                WHERE Name = 'TestAccount1'];

  //start test
  Test.startTest();
  PageReference pg = Page.AccountSearchPage;
  Test.setCurrentPageReference(pg);
  AccountSearchController controller = new AccountSearchController();
  controller.getAccount();
  controller.account = acc;
  controller.searchContacts();
  //search contacts which were created at test setup method
  controller.getContacts();
  controller.clear();
  Test.stopTest();
  //end test
 }
}

Now try running the test class, and you will notice that your controller will be covered 100%.

That’s it. You have finally learned how to prepare test data for your test classes. If you have any queries, please post a comment.

Until next time, ADIOS friends!!!

 

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s