Newer Version Available
Accessing Private Test Class Members
Test methods are defined in a test class, separate from the class they test. This can present a problem when having to access a private class member variable from the test method, or when calling a private method. Because these are private, they aren’t visible to the test class. You can either modify the code in your class to expose public methods that will make use of these private class members, or you can simply annotate these private class members with TestVisible. When you annotate private or protected members with this annotation, they can be accessed by test methods and only code running in test context.
This example shows how TestVisible is used with private member variables, a private inner class with a constructor, a private method, and a private custom exception. All these can be accessed in the test class because they’re annotated with TestVisible. The class is listed first and is followed by a test class containing the test methods.
1swfobject.registerObject("clippy.codeblock-0", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public class VisibleSampleClass {
18 // Private member variables
19 @TestVisible private Integer recordNumber = 0;
20 @TestVisible private String areaCode = '(415)';
21 // Public member variable
22 public Integer maxRecords = 1000;
23
24 // Private inner class
25 @TestVisible class Employee {
26 String fullName;
27 String phone;
28
29 // Constructor
30 @TestVisible Employee(String s, String ph) {
31 fullName = s;
32 phone = ph;
33 }
34 }
35
36 // Private method
37 @TestVisible private String privateMethod(Employee e) {
38 System.debug('I am private.');
39 recordNumber++;
40 String phone = areaCode + ' ' + e.phone;
41 String s = e.fullName + '\'s phone number is ' + phone;
42 System.debug(s);
43 return s;
44 }
45
46 // Public method
47 public void publicMethod() {
48 maxRecords++;
49 System.debug('I am public.');
50 }
51
52 // Private custom exception class
53 @TestVisible private class MyException extends Exception {}
54}1swfobject.registerObject("clippy.codeblock-1", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17// Test class for VisibleSampleClass
18@isTest
19private class VisibleSampleClassTest {
20
21 // This test method can access private members of another class
22 // that are annotated with @TestVisible.
23 static testmethod void test1() {
24 VisibleSampleClass sample = new VisibleSampleClass ();
25
26 // Access private data members and update their values
27 sample.recordNumber = 100;
28 sample.areaCode = '(510)';
29
30 // Access private inner class
31 VisibleSampleClass.Employee emp =
32 new VisibleSampleClass.Employee('Joe Smith', '555-1212');
33
34 // Call private method
35 String s = sample.privateMethod(emp);
36
37 // Verify result
38 System.assert(
39 s.contains('(510)') &&
40 s.contains('Joe Smith') &&
41 s.contains('555-1212'));
42 }
43
44 // This test method can throw private exception defined in another class
45 static testmethod void test2() {
46 // Throw private exception.
47 try {
48 throw new VisibleSampleClass.MyException('Thrown from a test.');
49 } catch(VisibleSampleClass.MyException e) {
50 // Handle exception
51 }
52 }
53
54 static testmethod void test3() {
55 // Access public method.
56 // No @TestVisible is used.
57 VisibleSampleClass sample = new VisibleSampleClass ();
58 sample.publicMethod();
59 }
60
61}The TestVisible annotation can be handy when you upgrade the Salesforce API version of existing classes containing mixed test and non-test code. Because test methods aren’t allowed in non-test classes starting in API version 28.0, you must move the test methods from the old class into a new test class (a class annotated with isTest) when you upgrade the API version of your class. You might run into visibility issues when accessing private methods or member variables of the original class. In this case, just annotate these private members with TestVisible.