You need to sign in to do that
Don't have an account?

How do I test for an exception('addError') in a Trigger ?
Hi,
- Sorry to bother, but I found no answer to this wuestion either on the web, or in the dev forum, or in the Apex documentation -
I have a trigger, which detects error conditions and feeds errors to the class or field.
This gives a nice result interactively, in the GUI.
But how do I write test code to catch these errors ? Is there a System.AssertException(), or the equivalent ?
trigger createOrder on Asset (after insert, after update) {[...] if (price.get(a.Product2Id) == NULL) { System.debug(' error : no active price'); a.Product2Id.addError('no active price on the Product'); }[...]}
Hi RupB,
I worked out a solution for a similar case I had where addError() was used for a record and not for a field.
I believe though it should work for your case too.
The idea is to:
a. Write code in the test class that will cause the trigger to 'addError()'.
b. Surround the above test class code with try - catch.
c. Assert that an exception is thrown and that the exception message is the same one you created with 'addError()'.
Here's an example (partly pseudo) code from both trigger and test class:
Trigger:
if(myRecord.MyField == some value)
myRecord.addError('My Error Message');
Test Class:
try
{
MyRecord.MyField = a value that will cause an error;
update MyRocord;
throw new MyException('An exception should have been thrown by the trigger but was not.'); // 1. If we get to this line it means an error was not added and the test class should throw an exception here. 2. MyException class extends Exception.
}
catch(Exception e)
{
Boolean expectedExceptionThrown = e.getMessage().contains('My Error Message')) ? true : false;
System.AssertEquals(expectedExceptionThrown, true);
}
Let me know if this did the work.
All Answers
Hi RupB,
I worked out a solution for a similar case I had where addError() was used for a record and not for a field.
I believe though it should work for your case too.
The idea is to:
a. Write code in the test class that will cause the trigger to 'addError()'.
b. Surround the above test class code with try - catch.
c. Assert that an exception is thrown and that the exception message is the same one you created with 'addError()'.
Here's an example (partly pseudo) code from both trigger and test class:
Trigger:
if(myRecord.MyField == some value)
myRecord.addError('My Error Message');
Test Class:
try
{
MyRecord.MyField = a value that will cause an error;
update MyRocord;
throw new MyException('An exception should have been thrown by the trigger but was not.'); // 1. If we get to this line it means an error was not added and the test class should throw an exception here. 2. MyException class extends Exception.
}
catch(Exception e)
{
Boolean expectedExceptionThrown = e.getMessage().contains('My Error Message')) ? true : false;
System.AssertEquals(expectedExceptionThrown, true);
}
Let me know if this did the work.
Sounds great, I will give it a try.
Rup
Hi sfdccoder1, thanks for the tip which works well.
Here is some more precise error detection code, especially for errors on fields ; in my case, I am detecting an error on the Product2Id field of an Asset :
catch(Exception e) {
System.Assert(e.getMessage().contains('FIELD_CUSTOM_VALIDATION_EXCEPTION'));
System.Assert(e.getMessage().contains('Product2Id'));
System.Assert(e.getMessage().contains('My Error Message'));
}
I hope this helps.
Cheers,
Rup
Hi I need to write test class for the following trigger, but i could able to cover 65%.
"a.addError" is not covering, how to Achieve more then 75%?
trigger doesn't have to have more than 75% coverage, that rule just applies to regular Apex classes.
sfdccoder1 Thanks for the help. This works great. I combined your answer with the specifics from RupB and checked my custom message, though I didn't throw an exception in the try block:
Note: I didn't understand at first why the exception in the try block is neccesary, but it is. When I excluded it the record could update successfully and the test would "pass". The exceptions throws an error if the record updates successfully, which in my test case it should not:
I'd always suggest that it is better for a test to fail off the back of an assertion than an exception (I accept that in the background these things are probably defined in the same way).
In this case I would replace the new exception that is raised with an assertion that should fail if the DML operation (in this case) succeded when it shouldn't have.
Using the previous example (I've assumed this is a custom object named Center__c):