Category Archives: testmethod

Apex Mocks and Enterprise Patterns (First in a Series)

It took me a bit to get here but I can unequivocally state that Apex Mocks is well worth learning to improve your unit testing.

This blog post aims at the Apex developer who doesn’t have Java Mockito experience (which was me). Since most of the code at our org relies on the Apex Enterprise Patterns, the examples herein will exploit that. The most useful reference to me was chapter 11 – Unit Testing of Enterprise Architecture although there were some typos in the code examples in my printed copy.

The scenario
You have a CasesService, method reopen(set csIds)

Here’s the code: Note use of the Unit of Work Pattern

public virtual class CasesServiceImpl implements ICasesService{

    *	reopen	- reopen a set of Cases
    public virtual void reopen(set<ID> csIds) {
        try {
            fflib_ISobjectUnitOfWork uow = Application.UnitOfWork.newInstance();
        catch (Exception e) {
            throw new CasesService.CaseReopenException(e.getTypeName() + ' ' + e.getMessage() + ' ' + e.getStackTraceString());

    public virtual void reopen(fflib_ISobjectUnitOfWork uow, set<ID> csIds) {
        for (ID csId : csIds) {
            uow.registerDirty(new Case(Id = csId, Status = Cases.STATUS_NEW));

I’m presuming if you are reading this, that you already know the Apex Enterprise Pattern and have created the ICasesService.cls, CasesService.cls, and updated the Application.cls.

Unit testing the service
In “classic” Apex development, you would test the CasesServiceImpl.reopen(set csIds) method by creating via DML a Case record (this might also require creating an Account and Contact record). Sort of like this:

@isTest private static void testCaseReopen() {
   Account[] mockAccts = new list<Account> {
     new Account(...),
     new Account(...)
   insert mockAccts;
   // and so on for the Contacts (mockContacts) and Cases (mockCases)

   CasesService.reopen(new set<ID> (new map<ID,Case>(mockCases).keySet());
   Case[] resultCases [select Id, Status from Case];
   for (Integer i = 0; i < resultCases.size(); i++)
                          '['+i+'] Status should be New');

So boring. And so much DML that makes your tests run longer – especially if you have hundreds or thousands of tests. You have to query the database to test your asserts. Think about testing Opportunities – Accounts, Contacts, Opportunities, Pricebooks, Product2s, PricebookEntries, and OpportunityLineItems may all have to be inserted into the database.

And here’s the beauty
Because you are using Apex Enterprise Patterns, you recognize that the reopen method only needs to be passed in Case Ids and then verified that the Cases were registered as dirty and that commitWork was called.

  • You don’t need real Cases to generate valid Case Ids
  • You don’t need to query the updated records to see if the Status was changed. Instead, you just need to know that registerDirty() was called with the expected status of ‘New’. As long as commitWork() was called, you can rely on the updates being done (written to the database) because commitWork() is already unit tested by the fflib library.

So, what does the unit test look like?

I’ll start off by saying that the syntax takes a bit of time getting used to. I’ll try to comment each step

@isTest private static void testReopen() {
  /** variable mocks represents the mocking framework object. 
     You can call it anything **/
  fflib_ApexMocks mocks = new fflib_ApexMocks();  // required and first
  // Given Case Ids to reopen 
  /** We use fflib to generate valid-for-the-sobjectType IDs **/
  ID[] mockCaseIds = new list<ID>();
  for (Integer i = 0; i < 2; i++) // 2 is arbitrary but goal is bulk testing 	

  // Given mock UnitOfWork
  fflib_SobjectUnitOfWork mockUow = (fflib_SobjectUnitOfWork) 
  Application.UnitOfWork.setMock(mockUow); // inject the mock for fflib factories

  /** Wrap your service call in try catch so you can easily debug any errors **/
  // When service invoked
  try {
   CasesService.reopen(new set<ID>(mockCaseIds)); 
  catch(Exception e) {
   System.assert(false,'snb, service method sb success; ' + showException(e));

  // Then verify Case status is New and objects committed 
  /** mocks.verify takes two arguments:
       1 - the object being mocked - in this case, the UnitOfWork
       2 - an object of type fflib_VerificationMode. 
           This object supports a fluent pattern with methods:
            times(n) - how many times the mock object's method M is called
            atLeast(n) - method called at least n times
            atMost(n) - method called at most n times
            atLeastOnce() - method called at least one time
            between(m,n) - method called between m and n times
            never() - method never called
            calls(n) - method called n times w/ InOrder verifier (see doc)
            description(text) - equivalent to the third argument for System.assertEquals()
       Once cast to the type of the mock object, then verification is that the 
       registerDirty method was called (twice) with an Sobject of type Case
                  .description('both Cases should be marked as Closed'))

  /** In this verify, assert registerDirty was called with an SObject matching 
      1 - Case.Id = the first mocked CaseId
      2 - Case.Status is 'New'

     This is done with a matcher (type = fflib_Match) argument. 
     The framework looks to see if the method (registerDirty) 
     was called with an argument that "matches" the matcher.

     There are a large number of matchers, see class
     fflib_Match (most of the Mockito matchers are mirrored). 
     One of the Apex-specific ones is sObjectWith that takes a map of
     SObjectField => Object

                  .description('Case[0] sb reopened'))
   .registerDirty(fflib_Match.sObjectWith(new map<SObjectField,Object> {
        Case.ID => mockCaseIds[0],    																			
        Case.Status => Cases.STATUS_NEW}));
  /** In this verify, assert the second Case ID also became status New **/
                  .description('Case[1] sb reopened'))
   .registerDirty(fflib_Match.sObjectWith(new map<SObjectField,Object> {
        Case.ID => mockCaseIds[1],    																			
        Case.Status => Cases.STATUS_NEW}));

  /** Finally, assert records were committed to Database. 
      As commitWork has no args there is no Matcher **/

                   .description('both Cases should be committed'))


Some meta remarks

  1. Using ApexMocks requires some wordy syntax that is not immediately apparent when you first see it
  2. It is especially useful for unit testing smallish methods that have few dependencies (which is how they should be written in the first place). Doing unit testing improves your confidence that methods will do what they are supposed to do when orchestrated into larger transactions.
  3. You can mock only non-static methods of objects.
  4. You need to invest time in learning how Matchers work. The class fflib_Match and fflib_ApexMocksTest are helpful. So are Mockito books and the Mockito web site
  5. As we’ll see in subsequent posts, you can mock selectors including formula fields and system audit fields without having to do any DML or SOQL. You can also mock the domain layer and service layer, and for that matter any non-static object method (except async)

The goal of this post was to explain the syntax. Try it out on a small class and you’ll feel you are up’ing your Unit test game, hence leaving a stronger legacy of test code to yourself, your team members, and your successors.

Testing a Batchable + Queueable + Schedulable

It isn’t super clear in the documentation (V36) what happens in a test method when a Batchable, Queueable, and Schedulable are involved within the Test.startTest()...Test.stoptest() execution scope.

The system executes all asynchronous processes started in a test method synchronously after the Test.stopTest statement

So, I decided to do a simple experiment:

The class (acts as both a batchable, queueable, and schedulable)

public with sharing class FooBatchableQueueable 
             implements Database.Batchable<Sobject>, Queueable {
    public Database.QueryLocator start(Database.BatchableContext bc) {
    	System.debug(LoggingLevel.INFO,'Entered Batchable start()...');
    	return  Database.getQueryLocator([select id from Group 
                                              where DeveloperName = 'Foo']);
    public void execute(Database.BatchableContext bc, List<Group> scope) {
    	System.debug(LoggingLevel.INFO,'Entered Batchable execute()...');
    	System.enqueueJob(new FooBatchableQueueable());
    	System.debug(LoggingLevel.INFO,'within Batchable execute(), after enqueuing the job...');
    public void finish(Database.BatchableContext bc) {
    	System.schedule('FooSchedulable','0 0 0 1 1 ?', new FooSchedulable());
    	System.debug(LoggingLevel.INFO,'within Batchable finish(), after scheduling');
    public void execute(QueueableContext qc) {
    	System.debug(LoggingLevel.INFO,'reached Queueable execute()');

    public class FooSchedulable implements Schedulable {
    	public void execute(SchedulableContext sc) {
    		System.debug(LoggingLevel.INFO,'reached Schedulable execute()');

And the testmethod

private with sharing class FooBatchableQueueableTest {
    @isTest private static void testBatchableQueueable() {
    	insert new Group(DeveloperName='Foo', name='Foo', type='Regular');
    	Database.executeBatch(new FooBatchableQueueable());
    	//	Async batchable should execute, then queueable,  
        //      then schedulable. Or do they? See debug log

And, what does happen?

  1. The batchable start() and execute() execute fine.
  2. The execute() calls System.enqueueJob(..)
  3. The Queueable job starts, and its execute() method is invoked. See the debug Log
  4. The batchable finish() method executes. It does a System.schedule() on a new object.
  5. The schedulable’s execute does not start.

Debug log

Entered Batchable start()…
Entered Batchable execute()…
within Batchable execute(), after enqueuing the job…
reached Queueable execute()
Entered Batchable finish()…
within Batchable finish(), after scheduling


  • Both the batchable and the queueable, as async transactions are executed “synchronously” once the Test.stopTest() is reached in the testmethod.
  • You definitely cannot assume that the batch finish() will execute before the queueable execute().
  • The constructor for the schedulable class will get invoked, but not its execute() method. You can see no debug log from within the schedulable’s execute().
  • You will need to explicitly test the schedulable by mocking the environment prior to its scheduling and then invoking in a separate testmethod.

Testing Viewstate in Apex testmethods

If you have a controller plus VF page that could be subject to viewstate issues and you want to avoid introducing viewstate issues once you have already tested some released version of your code, how should you go about doing this?

There is (as of V36.0), no PageReference method getViewStateSize() which would be the obvious choice.

So, is there a way to approximate the viewstate and verify it doesn’t grow as more data volume increases?

First Principles: What is Viewstate comprised of?

Viewstate is used to preserve state across HTTP stateless protocol as the page interacts with the controller via GETs and POSTs (at least until a client-side redirect occurs). From the Salesforce Developer Doc, Viewstate is made up of:

  • All non-transient data members in the associated controller (either standard or custom) and the controller extensions.
  • Objects that are reachable from a non-transient data member in a controller or controller extension.
  • The component tree for that page, which represents the page’s component structure and the associated state, which are the values applied to those components.
  • A small amount of data for Visualforce to do housekeeping.

So, from a testmethod point of view, we have access to the first two: non-transient data members and their reachable objects. The component tree will vary in size depending on how many components are rendered – and this typically varies with the number of list elements in apex:pageBlockTables, apex:dataTables, and apex:repeats. The Visualforce housekeeping space consumption is not available to us.

Steps to take
Assuming we have followed the excellent guidelines in Visualforce in Practice, Chapter 13, Visualforce Performance and Best PracticesRapidfire Rendering of Visualforce Pages, what remains is to use the Apex testmethods as a regression suite to early warn you if you have introduced a viewstate regression, at least from the controller side.

Note, there are ways to avoid Viewstate altogether via client-side techniques such as Javascript Remoting but for purposes of this Blog post, let’s assume you have a traditional VF controller + VF markup.

Here’s a coding approach to use in your testmethod:

@isTest private static void testViewState() {
  // Mock n Sobjects
  MyController ctlr = new Controller();  // same principle applies for extensions
  // exercise setters, getters, and ajax action methods that process all n records 
  Integer ctlrSerializedSize = Json.serialize(ctlr);  // get size of controller, serialized

  // mock another n SObjects so we have 2n total
  ctlr = new Controller();  
  // exercise setters, getters, and ajax action methods that process all 2n records 
                      'non transient size of controller should stay flat');


  1. For Json.serialize to work, you can’t have any non-transient, unserializable variables like System.SelectOption. Use methods rather than getter properties. A list of restrictions can be found in the Apex Developer Doc – JSON Support. Some things may be hard to work around.
  2. The equality assert given in the code sample most likely works only if the same input conditions are used for the test on n records as is used on 2n records.
  3. I’ll say it again, this won’t test the number of VF apex:components generated by 2n versus n — that could blow up your view state. Hopefully you addressed this the first time with your design by following the aforementioned VF in Practice guidelines, Chapter 13.

Builder pattern – in testmethod asserts

A common problem in business applications is to test multiple field values set by some service in an SObject. Normally, you might start down via this approach:

// ...code that updates some Opportunity

// now verify against expected values
Opportunity oActual = [select amount, closeDate, stagename from Opportunity where ...];
System.assertEquals(1000.0, oActual.amount);
System.assertEquals(Date.newIstance(2020,1,1), oActual.closeDate);
System.assertEquals('Closed Won',oActual.Stagename);

But this has several problems.

  1. It is tedious to type
  2. The testmethod stops on the first error yet other errors may be lurking. This is especially true if you have to verify many SObject fields. So, you end up running a test, finding an error, then fixing, then rerunning, then exposing a new error. Rinse and repeat and most likely, your attention has wandered into social media before too long.

Thanks to my colleagues Adrian Larson, sfdcfox and Keith C on Salesforce Stackexchange, I was introduced to the Builder Pattern. I decided to apply it to this issue.

I was looking to get all field verify errors for an SObject exposed in a single System.assert. So, the goal was to code this:

  .withStage('Closed Won')

that, if it doesn’t verify, displays the assertion failure as:

System.AssertException: Assertion Failed: Expected: , Actual:
AccountId Expected: 00540000000wbFSAAY vs. Actual: 0014000000HQGCMAA5
CloseDate Expected: null vs. Actual: 2006-10-14 00:00:00

So, here goes the code – one base (super) class that does all the work and one , each, domain (SObject-specific) class.

The base (super) class

public abstract class SObjectVerify {
	//	-------------------------------------
	//	Inner Class to track Variances between 
	//	expected and actual values for a given field
	//	-------------------------------------
	private class Variance {
		Object				actVal;
		Object				expVal;
		private Variance(Object expVal, Object actVal) {
			this.expVal		= expVal;
			this.actVal		= actVal;
	private map<Schema.SobjectField,Variance> fldToVarianceMap = new map<Schema.SobjectField,Variance>();
	public static final String NO_ERRORS	= '';	// Used by caller in system.assert as expectedResult
    private Sobject	actSobj;	// the actual Sobject
    // If all expected values match all actuals, 
    //	return NO_ERRORS, otherwise, return a line-broken string of variances
    protected String getResults() {
    	String res 		= NO_ERRORS;
    	for (Schema.SobjectField fld : fldToVarianceMap.keySet())
    		res += '\n   ' + fld + ' Expected: ' + fldToVarianceMap.get(fld).expVal + 
    			     ' vs. Actual: ' + fldToVarianceMap.get(fld).actVal;
    	return res;	

	//	(super) constructor
	public SobjectVerify(SObject actSobj) {this.actSobj = actSobj;}
	//	Builder pattern, returns ourselves after comparing 
	//	the actualFldVal vs expectedFldVal, stashing variances in a map
	protected SObjectVerify verify(Object expVal, Schema.SObjectField fld) {
		Object actVal	= this.actSobj.get(fld);
		if (expVal == null) {
			if (actVal != expVal)
				this.fldToVarianceMap.put(fld,new Variance(expVal,actVal));
		if (expVal instanceOf Blob) {
			if ((Blob) actVal != (Blob) expVal) 
				this.fldToVarianceMap.put(fld,new Variance(expVal,actVal));
		if (expVal instanceOf Boolean) {
			if ((Boolean) actVal != (Boolean) expVal) 
				this.fldToVarianceMap.put(fld,new Variance(expVal,actVal));
		if (expVal instanceOf Date) {
			if ((Date) actVal != (Date) expVal) 
				this.fldToVarianceMap.put(fld,new Variance(expVal,actVal));
		if (expVal instanceOf DateTime) {
			if ((DateTime) actVal != (DateTime) expVal) 
				this.fldToVarianceMap.put(fld,new Variance(expVal,actVal));
		if (expVal instanceOf Decimal) {
			if ((Decimal) actVal != (Decimal) expVal) 
				this.fldToVarianceMap.put(fld,new Variance(expVal,actVal));
		if (expVal instanceOf ID) {
			if ((ID) actVal != (ID) expVal) 
				this.fldToVarianceMap.put(fld,new Variance(expVal,actVal));
		if (expVal instanceOf Integer) {
			if ((Decimal) actVal != (Integer) expVal) 
				this.fldToVarianceMap.put(fld,new Variance(expVal,actVal));
		if (expVal instanceOf String) {
			if ((String) actVal != (String) expVal) 
				this.fldToVarianceMap.put(fld,new Variance(expVal,actVal));
		return this;												

The domain (Sobject-specific) Class

public class OpportunityVerify extends SObjectVerify {
	//	Usage
	//	System.assertEquals(SObjectVerify.NO_ERRORS,OpportunityVerify.getInstance(someActualOpportunity)
	//							.withXXX(someExpectedValFldXXX)
	//							.withYYY(someExpectedValFldYYY)
	//							.results();
	//	If the assertion fails, System.assert displays for each field at variance (separated by \n):
	//		fldXXX expected: .... vs. actual: ....
	//		fldYYY expected: .... vs. actual: ....
	private SObject actSObj;   // actual Opportunity, to be compared with Expected Opportunity
	public OpportunityVerify withAccountId(Object expVal) 	{
           return (OpportunityVerify) verify(expVal,Opportunity.AccountId);
	public OpportunityVerify withAmount(Object expVal) 	{
           return (OpportunityVerify) verify(expVal,Opportunity.Amount);
	public OpportunityVerify withCampaignId(Object expVal) 	{
           return (OpportunityVerify) verify(expVal,Opportunity.CampaignId);
	public OpportunityVerify withCloseDate(Object expVal) 	{
           return (OpportunityVerify) verify(expVal,Opportunity.CloseDate);
	public OpportunityVerify withHasOli(Object expVal) 	{
           return (OpportunityVerify) verify(expVal,Opportunity.HasOpportunityLineItem);
	public OpportunityVerify withStage(Object expVal) 	{
           return (OpportunityVerify) verify(expVal,Opportunity.StageName);
	public static OpportunityVerify	getInstance(SObject actSobj) {
		return new OpportunityVerify(actSobj);
	public String results() {
		return super.getResults(); // super class returns either NO_ERRORS (empty string) or a single string of variances)
	public OpportunityVerify(SObject actualSobj) {

Additional advantages

  1. If you need to incrementally add new field verifications, you only need to add a new withXXX method to the theDomainObjectVerify class.

Some possible extensions

  1. Verify a batch of records in a single assert, with the errors indexed by the position in the list

Partial success and trigger firing

Yesterday, I was baffled by the following observed behavior:

  1. Insert six Contacts using Database.insert(cList,false), five of which had some validation error, one which succeeded
  2. The successful Contact, in the before insert trigger, derives the value of accountId, if null in the inserted record
  3. The system.assert to verify the defaulting of accountId failed, even though the debug log clearly showed that it was set

Further investigation of the debug log showed the before insert trigger for the successful Contact was executing twice, and in the second iteration, the defaulting of the accountId was not occurring.

Before insert trigger executed twice? Huh?

After some reductionist testing, I verified that this only happened when using optAllOrNothing = false in Database.insert(cList,false). That is, allow for partial successes. According to the documentation (in a section I had never read or paid attention to).

When errors occur because of a bulk DML call that originates from the SOAP API with default settings, or if the allOrNone parameter of a Database DML method was specified as false, the runtime engine attempts at least a partial save:

(1) During the first attempt, the runtime engine processes all records. Any record that generates an error due to issues such as validation rules or unique index violations is set aside.

(2) If there were errors during the first attempt, the runtime engine makes a second attempt that includes only those records that did not generate errors. All records that didn’t generate an error during the first attempt are processed, and if any record generates an error (perhaps because of race conditions) it is also set aside.

(3) If there were additional errors during the second attempt, the runtime engine makes a third and final attempt which includes only those records that didn’t generate errors during the first and second attempts. If any record generates an error, the entire operation fails with the error message, “Too many batch retries in the presence of Apex triggers and partial failures.”

It is the second point that is interesting – “the runtime engine makes a second attempt that includes only those records that did not generate errors” – ahhh, that is why the debug log showed two executions of before insert on the same record.

Now, why did the second attempt not default the Contact’s accountId using my Apex logic?

Answer: At the end of my before insert trigger handler, I set a static variable to prevent the trigger handler from re-executing (sort of a reflex action to avoid unnecessary SOQLs). Hence, when the second attempt at before insert was made, the static variable prevented the defaulting and the record saved successfully, except without a non-null AccountId. Hence the assertion failed.

A different portion of the SFDC Apex doc states:

When a DML call is made with partial success allowed, more than one attempt can be made to save the successful records if the initial attempt results in errors for some records. For example, an error can occur for a record when a user-validation rule fails. Triggers are fired during the first attempt and are fired again during subsequent attempts. Because these trigger invocations are part of the same transaction, static class variables that are accessed by the trigger aren’t reset. DML calls allow partial success when you set the allOrNone parameter of a Database DML method to false or when you call the SOAP API with default settings. For more details, see Bulk DML Exception Handling.

Note the sentence: “Because these trigger invocations are part of the same transaction, static class variables that are accessed by the trigger aren’t reset”.

So, while governor limits are not affected by the retry, the static variables remain persistent and hence the trigger handler derivation logic remained switched off as a result of the conclusion of the initial before insert trigger handler.

Removing the setting of the static variable solved the issue.

Batchable class – test data – callouts: How to test?

The short hand title for this post might also be System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out

Here’s the problem I recently faced:

  1. Batchable class that does callouts in the start() method.
  2. Testmethod needs to setup some test data before the batchable class executes

As you probably know if you are reading this ..

  • Testmethods can’t do callouts, you have to mock out the callout response using Test.setMock(..)
  • Async tasks like Database.executeBatch() or @future methods don’t execute in a test context until the Test.stopTest() method.

Naively, I constructed this basic testmethod:

insert new Account(name = '00test'); // create test data here
  Test.setMock(HttpCalloutMock.class, myMultiMockObject); // setup of multiMockObject omitted for clarity
  MyBatchableClass bClass = new MyBatchableClass();
  Database.executeBatch(bClass,2);  // scope is 2
Test.stopTest();  // SFDC executes the async task here
System.assert(...) //verify results

When you execute this test, you get System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out

I then tried to setup the test data in a different context like this:

System.runAs(someUserOtherThanRunningUser) {
   insert new Account(name = '00test'); // create test data here
  Test.setMock(HttpCalloutMock.class, myMultiMockObject); // setup of multiMockObject omitted for clarity
  MyBatchableClass bClass = new MyBatchableClass();
  Database.executeBatch(bClass,2);  // scope is 2
Test.stopTest();  // SFDC executes the async task here
System.assert(...) //verify results

When you execute this test, you get System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out

Aargh. SFDC doc as of V30 wasn’t much help here. Much Googling ensued. Thanks to tomlogic for the solution essence.

Here is what you have to do –avoid the use of Database.executeBatch() in the testmethod if one of the batchable class’s start(), execute() or finish() methods does a callout. Thus, you have to invoke the start(), execute(), finish() methods explicitly to verify your batchable class logic and get code coverage.

insert new Account(name = '00test'); // create test data here
  Test.setMock(HttpCalloutMock.class, myMultiMockObject); // setup of multiMockObject omitted for clarity
  Database.BatchableContext 	bc;
  MyBatchableClass bClass = new MyBatchableClass();
  // we execute the start() and prepare results for execute()
  // in my use case, start() does the callout; 
  // thus the testmethod mocks the results of the callout (assumed here to be accounts)
  // setup of custom Iterable and Iterator not shown
  MyIterable  itrbl = (MyIterable)bclass.start();  //start() returns an iterable, in my case, a custom iterable. Note the casting
  MyIterator  itrator = (MyIterator) itrbl.iterator();  // continue simulation of start() by constructing the iterator
  List<Account> aScopeList = new List<Account> ();      // create scope for execute() by iterating against the result of the mocked callout
  while (itrator.hasNext()) {

  // Now invoke execute() w/ Account list built via mocked callout invoked by start()

  // Finally, invoke finish()
Test.stopTest();  // SFDC executes the async task here
System.assert(...) //verify results

To recap, this approach accomplishes the following:

  1. It will test code coverage as start(), execute(), and finish() are all invoked as if SFDC were invoking them by Database.executeBatch().
  2. It avoids the System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out
  3. It allows you to test against the returned data from the mocked callout(s) thus isolating your testmethod to predictable responses.
  4. It tests your custom iterator, if you are using one
  5. It only requires a bit more setup to individually invoke start(), execute(), and finish() plus manual construction of what execute() would get if database.executeBatch() were called