Testing Example
The following example includes cases for the following types of tests:
- Positive case with single and multiple records
- Negative case with single and multiple records
- Testing with other users
The test is used with a simple mileage tracking application. The existing code for the application verifies that not more than 500 miles are entered in a single day. The primary object is a custom object named Mileage__c. The test creates one record with 300 miles and verifies there are only 300 miles recorded. Then a loop creates 200 records with one mile each. Finally, it verifies there are 500 miles recorded in total (the original 300 plus the new ones). Here’s the entire test class. The following sections step through specific portions of the code.
1@IsTest
2private with sharing class MileageTrackerTestSuite {
3
4 @IsTest
5 static void runPositiveTestCases() {
6
7 Double totalMiles = 0;
8 final Double maxtotalMiles = 500;
9 final Double singletotalMiles = 300;
10 final Double u2Miles = 100;
11
12
13 //Set up user
14 User u1 = [SELECT Id FROM User WHERE Alias='auser' WITH USER_MODE];
15
16 //Run As U1
17 System.RunAs(u1){
18
19
20 System.debug('Inserting 300 miles... (single record validation)');
21
22 Mileage__c testMiles1 = new Mileage__c(Miles__c = 300, Date__c = System.today());
23 insert as user testMiles1;
24
25 //Validate single insert
26 for(Mileage__c m:[SELECT miles__c FROM Mileage__c
27 WHERE CreatedDate = TODAY
28 and CreatedById = :u1.id
29 and miles__c != null WITH USER_MODE]) {
30 totalMiles += m.miles__c;
31 }
32
33 Assert.areEqual(singletotalMiles, totalMiles);
34
35
36 //Bulk validation
37 totalMiles = 0;
38 System.debug('Inserting 200 mileage records... (bulk validation)');
39
40 List<Mileage__c> testMiles2 = new List<Mileage__c>();
41 for(integer i=0; i<200; i++) {
42 testMiles2.add( new Mileage__c(Miles__c = 1, Date__c = System.today()) );
43 }
44 insert as user testMiles2;
45
46 for(Mileage__c m:[SELECT miles__c FROM Mileage__c
47 WHERE CreatedDate = TODAY
48 and CreatedById = :u1.Id
49 and miles__c != null WITH USER_MODE]) {
50 totalMiles += m.miles__c;
51 }
52
53 Assert.areEqual(maxtotalMiles, totalMiles);
54
55 }//end RunAs(u1)
56
57
58 //Validate additional user:
59 totalMiles = 0;
60 //Setup RunAs
61 User u2 = [SELECT Id FROM User WHERE Alias='tuser' WITH USER_MODE];
62 System.RunAs(u2){
63
64 Mileage__c testMiles3 = new Mileage__c(Miles__c = 100, Date__c = System.today());
65 insert as user testMiles3;
66
67 for(Mileage__c m:[SELECT miles__c FROM Mileage__c
68 WHERE CreatedDate = TODAY
69 and CreatedById = :u2.Id
70 and miles__c != null WITH USER_MODE]) {
71 totalMiles += m.miles__c;
72 }
73 //Validate
74 Assert.areEqual(u2Miles, totalMiles);
75
76 } //System.RunAs(u2)
77
78
79 } // runPositiveTestCases()
80
81 @IsTest
82 static void runNegativeTestCases() {
83
84 User u3 = [SELECT Id FROM User WHERE Alias='tuser' WITH USER_MODE];
85 System.RunAs(u3) {
86
87 System.debug('Inserting a record with 501 miles... (negative test case)');
88
89 Mileage__c testMiles3 = new Mileage__c( Miles__c = 501, Date__c = System.today() );
90
91 try {
92 insert as user testMiles3;
93 Assert.fail('DmlException expected');
94 } catch (DmlException e) {
95 //Assert Status Code
96 Assert.areEqual('FIELD_CUSTOM_VALIDATION_EXCEPTION', e.getDmlStatusCode(0));
97
98 //Assert field
99 Assert.areEqual(Mileage__c.Miles__c, e.getDmlFields(0)[0]);
100
101 //Assert Error Message
102 Assert.isTrue(e.getMessage().contains(
103 'Mileage request exceeds daily limit(500): [Miles__c]'),
104 'DMLException did not contain expected validation message:' + e.getMessage() );
105
106 } //catch
107 } //RunAs(u3)
108 } // runNegativeTestCases()
109
110
111} // class MileageTrackerTestSuitePositive Test Case
The following steps through the above code, in particular, the positive test case for single and multiple records.
- Add text to the debug log, indicating the next step of the
code:
1System.debug('Inserting 300 more miles...single record validation'); - Create a Mileage__c object and insert it into the
database.
1Mileage__c testMiles1 = new Mileage__c(Miles__c = 300, Date__c = System.today() ); 2insert as user testMiles1; - Validate the code by returning the inserted
records:
1for(Mileage__c m:[SELECT miles__c FROM Mileage__c 2 WHERE CreatedDate = TODAY 3 and CreatedById = :createdbyId 4 and miles__c != null WITH USER_MODE]) { 5 totalMiles += m.miles__c; 6 } - Use the Assert.areEqual method to
verify that the expected result is
returned:
1Assert.areEqual(singletotalMiles, totalMiles); - Before moving to the next test, set the number of total miles back to
0:
1totalMiles = 0; - Validate the code by creating a bulk insert of 200 records.First, add text to the debug log, indicating the next step of the code:
1System.debug('Inserting 200 Mileage records...bulk validation'); - Then insert 200 Mileage__c
records:
1List<Mileage__c> testMiles2 = new List<Mileage__c>(); 2for(Integer i=0; i<200; i++){ 3testMiles2.add( new Mileage__c(Miles__c = 1, Date__c = System.today()) ); 4 } 5insert as user testMiles2; - Use Assert.areEqual to verify that the
expected result is
returned:
1for(Mileage__c m:[SELECT miles__c FROM Mileage__c 2 WHERE CreatedDate = TODAY 3 and CreatedById = :CreatedbyId 4 and miles__c != null WITH USER_MODE]) { 5 totalMiles += m.miles__c; 6 } 7 Assert.areEqual(maxtotalMiles, totalMiles);
Negative Test Case
The following steps through the above code, in particular, the negative test case.
- Create a static test method called runNegativeTestCases:
1@IsTest 2static void runNegativeTestCases(){ - Add text to the debug log, indicating the next step of the
code:
1System.debug('Inserting 501 miles... negative test case'); - Create a Mileage__c record with 501 miles.
1Mileage__c testMiles3 = new Mileage__c(Miles__c = 501, Date__c = System.today()); - Place the insert statement within a
try/catch block. This allows you to catch the validation exception and
assert the generated error message. Use the Assert.fail method to clearly assert that you expect the
validation exception.
1try { 2 insert as user testMiles3; 3 Assert.fail('DmlException expected'); 4 } catch (DmlException e) { - Now use the Assert.areEqual and Assert.isTrue methods to do the testing.
Add the following code to the catch
block you previously
created:
1//Assert Status Code 2Assert.areEqual('FIELD_CUSTOM_VALIDATION_EXCEPTION', e.getDmlStatusCode(0)); 3 4//Assert field 5Assert.areEqual(Mileage__c.Miles__c, e.getDmlFields(0)[0]); 6 7//Assert Error Message 8Assert.isTrue(e.getMessage().contains( 9 'Mileage request exceeds daily limit(500): [Miles__c]'), 10 'DMLException did not contain expected validation message:' + e.getMessage() );
Testing as a Second User
The following steps through the above code, in particular, running as a second user.
- Before moving to the next test, set the number of total miles back to
0:
1totalMiles = 0; - Set up the next
user.
1User u2 = [SELECT Id FROM User WHERE Alias='tuser' WITH USER_MODE]; 2 System.RunAs(u2){ - Add text to the debug log, indicating the next step of the
code:
1System.debug('Setting up testing - deleting any mileage records for ' + 2 UserInfo.getUserName() + 3 ' from today'); - Then insert one Mileage__c
record:
1Mileage__c testMiles3 = new Mileage__c(Miles__c = 100, Date__c = System.today()); 2insert as user testMiles3; - Validate the code by returning the inserted
records:
1for(Mileage__c m:[SELECT miles__c FROM Mileage__c 2 WHERE CreatedDate = TODAY 3 and CreatedById = :u2.Id 4 and miles__c != null WITH USER_MODE]) { 5 totalMiles += m.miles__c; 6 } - Use the Assert.areEqual method to
verify that the expected result is
returned:
1Assert.areEqual(u2Miles, totalMiles);