{{announcement.body}}
{{announcement.title}}

How Do You Run a Unit Test in Apex?

DZone 's Guide to

How Do You Run a Unit Test in Apex?

To facilitate the development of robust, error-free code, Apex supports the creation and execution of unit tests.

· Performance Zone ·
Free Resource

To facilitate the development of robust, error-free code, Apex supports the creation and execution of unit tests. Unit tests are class methods that verify whether a particular piece of code is working properly. Unit test methods take no arguments, commit no data to the database, and send no emails. Such methods are flagged with the @isTest annotation in the method definition. Unit test methods must be defined in test classes, that is, classes annotated with @isTest.

For example:

Java
 




x


 
1
@isTest 
2
private class myClass {
3
 static void myTest() { 
4
       // code_block    } }



Here is the same test class as in the previous example but it defines the test method with the (now deprecated) testMethod keyword instead.

Java
 




xxxxxxxxxx
1


 
1
@isTest 
2
private class myClass {     
3
static testMethod void myTest() {
4
        // code_block    } }



Use the @isTest annotation to define classes and methods that only contain code used for testing your application. The @isTest annotation can take multiple modifiers within parentheses and separated by blanks. 

This example of a test class contains two test methods.

Java
 




xxxxxxxxxx
1


 
1
@isTest 
2
private class MyTestClass {
3
    // Methods for testing   @isTest static void test1() {
4
      // Implement test code   }   
5
 @isTest static void test2() {  
6
    // Implement test code   } 
7
}



Classes and methods defined as @isTest can be either private or public. The access level of test class methods doesn’t matter. You need not add an access modifier when defining a test class or test method. The default access level in Apex is private. The testing framework can always find the test methods and execute them, regardless of their access level.

Classes defined as @isTest must be top-level classes and can't be interfaces or enums.

Methods of a test class can only be called from a test method or code invoked by a test method; non-test requests can’t invoke it.

This example shows a class to be tested and its corresponding test class. It contains two methods and a constructor.

Java
 




xxxxxxxxxx
1
15


 
1
public class TVRemoteControl {
2
    // Volume to be modified    Integer volume;    
3
// Constant for maximum volume value    static final Integer MAX_VOLUME = 50;            
4
// Constructor    public TVRemoteControl(Integer v) {  
5
      // Set initial value for volume        volume = v;    }  
6
          public Integer increaseVolume(Integer amount) {
7
        volume += amount;        
8
if (volume > MAX_VOLUME) {   
9
         volume = MAX_VOLUME;        }  
10
       return volume;    }      
11
  public Integer decreaseVolume(Integer amount) {
12
        volume -= amount;        if (volume < 0) {    
13
        volume = 0;        }          return volume;    }  
14
          public static String getMenuOptions() {   
15
     return 'AUDIO SETTINGS - VIDEO SETTINGS';    }       }



This example contains the corresponding test class with four test methods. Each method in the previous class is called. Although there is sufficient test coverage, the test methods in the test class perform extra testing to verify boundary conditions. 

Java
 




xxxxxxxxxx
1
23


 
1
@isTest 
2
class TVRemoteControlTest { 
3
   @isTest static void testVolumeIncrease() {
4
        TVRemoteControl rc = new TVRemoteControl(10);        
5
Integer newVolume = rc.increaseVolume(15);        
6
System.assertEquals(25, newVolume);    }        
7
@isTest static void testVolumeDecrease() { 
8
       TVRemoteControl rc = new TVRemoteControl(20);        
9
Integer newVolume = rc.decreaseVolume(15);       
10
 System.assertEquals(5, newVolume);            } 
11
@isTest static void testVolumeIncreaseOverMax() {  
12
      TVRemoteControl rc = new TVRemoteControl(10);        
13
Integer newVolume = rc.increaseVolume(100);       
14
 System.assertEquals(50, newVolume);            }        
15
@isTest static void testVolumeDecreaseUnderMin() {
16
        TVRemoteControl rc = new TVRemoteControl(10);        
17
Integer newVolume = rc.decreaseVolume(100);        
18
System.assertEquals(0, newVolume);            }        
19
@isTest static void testGetMenuOptions() {        
20
// Static method call. No need to create a class instance.        
21
String menu = TVRemoteControl.getMenuOptions();        
22
System.assertNotEquals(null, menu);        
23
System.assertNotEquals('', menu);    } }



Unit Test Considerations

Here are some things to note about unit tests.

  • Starting with Salesforce integration API 28.0, test methods can no longer reside in non-test classes and must be part of classes annotated with isTest. See the TestVisible annotation to learn how you can access private class members from a test class.
  • Test methods can’t be used to test Web service callouts. Instead, use mock callouts. See Test Web Service Callouts and Testing HTTP Callouts.
  • You can’t send email messages from a test method.
  • Since test methods don’t commit data created in the test, you don’t have to delete test data upon completion.
  • If the value of a static member variable in a test class is changed in a testSetup or test method, the new value isn’t preserved. Other test methods in this class get the original value of the static member variable. This behavior also applies when the static member variable is defined in another class and accessed in test methods.
  • For some sObjects that have fields with unique constraints, inserting duplicate sObject records results in an error. For example, inserting CollaborationGroup sObjects with the same names results in an error because CollaborationGroup records must have unique names.
  • Tracked changes for a record (FeedTrackedChange records) in Chatter feeds aren't available when test methods modify the associated record. FeedTrackedChange records require the change to the parent record they're associated with to be committed to the database before they're created. Since test methods don't commit data, they don't result in the creation of FeedTrackedChange records. Similarly, field history tracking records can't be created in test methods because they require other sObject records to be committed first. For example, AccountHistory records can’t be created in test methods because Account records must be committed first.
Topics:
apex, performance, salesforce, tutorial, unit test, unit testing

Published at DZone with permission of Shailesh Chaudhary . See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}