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
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.
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.
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
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
isInstanceOfTypeaccepts 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.
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.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.
Assert.areEqual() instead of
System.assertEquals() for clarity
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
The following code uses
Assert.areEqual, the above code can be modified as below. Notice we replaced
Assert.areEqual and nothing else is changed.
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,
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.
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.
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.
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.