When writing unit tests for an extension provider class, sometimes we want to mock the super() method in the extension provider class. However, the Apex test framework does not support mocking objects or methods in a namespace that is different from where test classes are defined. This tutorial provides a workaround to allow us to mock super() in the extension provider class. To learn more about Apex’s namespace, refer to Default Namespaces in Apex on the Salesforce Developers blog.
The idea is to separate the logic for calling the super() default logic so that it can be mocked in the test.
Let’s walk through an example for testing the extension provider class.
Assume we have an extension provider class called Custom_Inventory that extends a Base Apex class CommerceDxSampleapp.CommerceDx_Inventory.
The Base Apex Class has its own namespace and is different from the org of the extension provider class.
Note
Base Apex Class
The base Apex class looks like this:
1global virtual class CommerceDxSampleapp.CommerceDx_Inventory {2 global virtual Integer calculateInventoryLevel(String webstoreId, String eventId){3 // Default Logic4 return 0;5}6}
Extension Provider Class
The Custom_Inventory class belongs to current org’s namespace._
Note
To create an extension provider, add a class that extends the base Apex class:
1public class Custom_Inventory extends CommerceDxSampleapp.CommerceDx_Inventory{2 public override Integer calculateInventoryLevel(String webstoreId, String eventId){3 // Invoke Base Class's default logic4 super.calculateInventoryLevel(webstoreId, eventId);5}6}
1. Add "Virtual" to Extension Provider Classes
To make sure that we can mock the default logic, add a method that only calls super() and make it overridable by marking it as virtual. We also need to mark the class as virtual.
Next, define the test class. (See Salesforce Developers to learn how to write an Apex test.)
MyTestClass
1@isTest2public class MyTestClass{3 @isTest4 public static void testCalculateInventory(){56}7}
3. Define the Inner Mock Class
Finally, define an inner mock class called Fake_Custom_Inventory to override the logic for the super() method that belongs to the base Apex class. Then the test method can use the mock class to return the expected result for the super() logic.
1@isTest2public class MyTestClass{3 @isTest4 public static void testCalculateInventory(){5 Fake_Custom_Inventory fake_Custom_Inventory = new Fake_Custom_Inventory();6 // Assert the result is the same as mocked result defined below7 String webstoreId = 'fakeWebstoreId';8 String eventId = 'fakeEventId';9 System.assertEquals(-1, fake_Custom_Inventory.calculateInventoryLevel(webstoreId, eventId));10}1112 // Create a mock private class in the test class13 private class Fake_Custom_Inventory extends Custom_Inventory{14 public override Integer callDefault(String webstoreId, String eventId){15 // Return a mocked result for testing16 return -1;17}18}19}