One of the great new enhancements in the Winter ’23 release is a dedicated Assert class. As we continue to build on our investment with Apex and testability, this update will make it easier to find all the assert methods you need in one place. Let’s take a look at how this compares to the current methods of asserting your tests, and how you can start to use it today.
Introducing the Apex Assert class
Apex already has system methods, such as assert
, assertEquals
, and assertNotEquals
, to write assertions in Apex tests. These methods have been here for decades and work as intended, even today. We have no immediate plans to retire these system methods. Still, we encourage you to use the new Assert class and look for opportunities to use it in your existing code. The new Assert class has additional methods for you to write clear and intentional assertions. The other notable advantage of the new Assert class is that if the assertion results in an exception, it’s easier to read and understand.
In order to demonstrate the new class, I have updated the Apex assertions for all the test classes for the apex-recipes sample app. Along the way, I got an opportunity to use some of the new methods of the Assert class. In this blog, I will share some areas that you can look at in your codebase where you could use the new Assert class to improve the readability of the Apex tests.
Using Assert.fail()
to intentionally return a fatal error
Before the new Assert class, you would have encountered patterns, like the one below, to intentionally halt the code execution in your test class and return a fatal error.
The above code is less readable. The statement System.assert(false)
makes it less obvious that we want to fail the code intentionally. Let’s modify the above code to use the new Assert.Fail()
method. The modified code is below.
As you can observe, it becomes obvious with the word “fail” that we want to fail the code execution at a specific line if the expected exception hasn’t occurred.
Using Assert.isInstanceOfType()
to assert object instance
Let’s take an example pattern of writing assertions in Apex test code to assert that the object instance is of the specified type with the System.assert
method.
Modifying the above code to use the new Assert class and using the isIntanceofType()
method, we will see the readability is much improved.
TIP: Note that Assert method
isInstanceOfType
accepts the first parameter as the actual type, followed by the expected type and then the custom message. While for the rest of the Assert methods, the first parameter is the expected result followed by the actual result and then the custom message.
Using Assert.isNull()
to assert the null values
In order to add clarity to the way that you are checking null values in your tests, we have introduced the Assert.IsNull()
and Assert.isNotNull()
methods. Let’s take a look at how this compares to the system methods and how we can increase readability.
The code below uses System.assert
and has an expression to check if the object is NOT null.
The code above is correct, but because the Assert class now offers a suitable method for null comparison, it can be made more readable as follows.
Using Assert.areEqual()
instead of System.assertEquals()
for clarity
The Assert.areEqual
method is very similar to the System.assertEquals
. It asserts that two values are equal. The advantage of the new class is that it reads better, and if assertions error during test execution, you have a better error message. Here is a simple example comparing the usage of System.assertEquals
vs Assert.areEqual
.
The following code uses System.assertEquals
.
With Assert.areEqual
, the above code can be modified as below. Notice we replaced System.assetEquals
with Assert.areEqual
and nothing else is changed.
Using Assert.isTrue()
instead of System.assert()
for clarity
At this point, you have observed how these new methods have more precise names than their previous counterparts. However, this one can get a little bit more confusing, System.assert()
and Assert.isTrue()
function in similar ways, but their names are not precisely the same. Thankfully, it is not Assert.assert(condition)
for even more confusion!
The following code uses System.assert
for assertions.
With Assert.isTrue
, the above code is modified as shown below. Notice how the code is more readable and obvious.
There are also NOT operator equivalent methods available in the Assert class. For example, there is an Assert.isFalse()
that asserts that the condition is false. The goal with Assert.isFalse()
is to replace a snippet of code-like System.assert(!containsForce)
scenario with the leading negation. The Assert.isFalse()
clarifies that the condition should be false.
Explore the whole list of the available methods in the Apex documentation.
Crafting good error messages
You may have noticed that all of my code snippets in this blog use the optional last parameter of Assert methods to add a custom error message. It is good practice to write clear error messages, so that if the test fails later, it should help you diagnose what failed.
The new Assert class methods also encourage crafting good messages by restricting the last parameter to a string. The System.assert()
accepted an object for the message and converted that object to a string representation, often being less helpful for debugging failed tests. The new Assert methods explicitly need a string. So you cannot use a sObject
or a Map in the message parameters. We want you to be very explicit about the failure message and carefully think about the error messages.
Final tip
It is also possible that you already have a class named “Assert” in your System. The Salesforce Platform does not stop you from creating a class with Name Assert, but having that class in your org can cause conflicts when you try to use the new Assert class from the System namespace. Thankfully, there is a solution. You can append the System namespace to the Assert class in such scenarios. For example, write System.Assert.areEqual
instead of Assert.areEqual
and you can safely use the new classes.
Conclusion
The new System.Assert
class provides methods that handle all types of logical assertions and comparisons. When you use an assert method intended for a specific condition, the clarity of your Apex code improves. And if the assertion results in an exception, it’s easier to read and understand.
We updated every test class in the apex-recipes sample app to use the new System.Assert
classes. We have been pleased with how smooth it was to update the previous assertions, thanks to the continuous integration systems we have in place for the project. In the future, for all the new Apex tests we write, we will make sure to use the new Assert class.
About the author
Mohith Shrivastava is a Developer Advocate at Salesforce with a decade of experience building enterprise-scale products on the Salesforce Platform. He is presently focusing on the Salesforce Developer Tools, Apex, and Lightning Web Components at Salesforce. Mohith is currently among the lead contributors on Salesforce Stackexchange, a developer forum where Salesforce Developers can ask questions and share knowledge. You can follow him via his Twitter @msrivastav13.