Testing Versioned Behavior in Apex Code
When you change the behavior in an Apex class or trigger for different package
versions, it’s important to test that your code runs as expected in the different package
versions. You can write test methods that change the package version
context to a different package version by using the System.runAs method. You can only use System.runAs in a test method.
This sample shows a trigger with different behavior for different package versions. For more information about defining different behavior for package versions, see Version Apex Behavior.
1trigger oppValidation on Opportunity (before insert, before update) {
2
3 for (Opportunity opp : Trigger.new){
4
5 // Add a new validation to the package
6 // Applies to versions of the managed package greater than 1.0
7 if (System.requestVersion().compareTo(new Version(1,0)) > 0) {
8 if (opp.Probability >= 50 && opp.Description == null) {
9 opp.addError('All deals over 50% require a description');
10 }
11 }
12
13 // Validation applies to all versions of the managed package.
14 if (opp.IsWon == true && opp.LeadSource == null) {
15 opp.addError('A lead source must be provided for all Closed Won deals');
16 }
17 }
18}The following test class uses the runAs method to verify the trigger’s behavior with and without a specific version:
1@IsTest
2private class OppTriggerTests{
3
4 static testMethod void testOppValidation(){
5
6 // Set up 50% opportunity with no description
7 Opportunity opp = new Opportunity();
8 opp.Name = 'Test Job';
9 opp.Probability = 50;
10 opp.StageName = 'Prospect';
11 opp.CloseDate = System.today();
12
13 // Test running as latest package version
14 try{
15 insert opp;
16 }
17 catch(DMLException e){
18 Assert.isTrue(
19 e.getMessage().contains(
20 'All deals over 50% require a description'),
21 e.getMessage());
22 }
23
24 // Run test as managed package version 1.0
25 System.runAs(new Version(1,0)){
26 try{
27 insert opp;
28 }
29 catch(DMLException e){
30 Assert.isFalse(false, e.getMessage());
31 }
32 }
33
34 // Set up a closed won opportunity with no lead source
35 opp = new Opportunity();
36 opp.Name = 'Test Job';
37 opp.Probability = 50;
38 opp.StageName = 'Prospect';
39 opp.CloseDate = System.today();
40 opp.StageName = 'Closed Won';
41
42 // Test running as latest package version
43 try{
44 insert opp;
45 }
46 catch(DMLException e){
47 Assert.isTrue(
48 e.getMessage().contains(
49 'A lead source must be provided for all Closed Won deals'),
50 e.getMessage());
51 }
52
53 // Run test as managed package version 1.0
54 System.runAs(new Version(1,0)){
55 try{
56 insert opp;
57 }
58 catch(DMLException e){
59 Assert.isTrue(
60 e.getMessage().contains(
61 'A lead source must be provided for all Closed Won deals'),
62 e.getMessage());
63 }
64 }
65 }
66}