A Pattern for Apex Test Code So You Can Forget About Required Fields

Yeah, yeah, yeah, just take me to the code.

I recently had the opportunity to start writing some code in a brand new org, which got me thinking about the best way to do test object creation. You know, that annoying problem where you need to generate an Account in a test class about 77 times. Here’s a pattern I came up with.

This method involves some overhead but it has the advantages of (1) allowing you to set defaults for certain objects so you don’t have to worry about them – for some objects create them with all defaults with just one line, and (2) a generic, repeatable pattern.

It’s based on an abstract class that implements the base operations using some generic sObject magic outlined here.

A lot of code in this post, bear with me.

(That's a basic version, for something more robust, look here.)

For each object you will use, you need to create a class that implements the abstract factory class.

Then, in your test code you would need to instantiate the factory for each object, and set values in the Map using setFieldValue.

NB: You will need to be careful about the Map (setFieldValue calls), since in all subsequent calls the values class variable will still contain its prior values. That could cause logic issues if you’re setting fields you didn’t intend to. The abstract class contains a clearFieldValues() method to clear it out if necessary.

Seems like.. That’s a Lot of Work For Not a Lot of Benefit?

No doubt, it’s wordy. But here’s why it’s worth it. The big benefit is that all your defaults/required fields are taken care of – if you had a required field on your Contact, the code would pre-fill it for you. Or, you can override the default by setting the value in the Map.

I created a custom metadata type that allows you to fill in defaults; if you look in the abstract class above, it calls a fillDefaults() method. This goes into the custom metadata and populates the required fields. For example, you can set the default Name for Accounts.


Popular posts from this blog

What Happens To "Inflight" Process Builders When You Activate a new Version?

Custom Lookup For Flows to Avoid "Disjunctions Not Supported"

"Disjunctions not supported" - Why Custom Metadata and Flow Don't Mix