I would know how to cover, with the test class, the catch block in my apex trigger:
APEX TRIGGER:
try{
update olis_updated;
} catch (DMLException e){
for (OpportunityLineItem o :olis){
o.addError('There was a problem setting Product_Category__c ');
}
}
TEST CLASS:
I've tried like following, but it doesn't work
// GENERATE EXECEPTION
test.startTest();
lineItem1.id=lineItem2.id;
update lineItem1;
test.stopTest();
How can i generate an exeception?
Thanks in advantage for any advice.
BR
Best Answer
Not all code that is written can be covered. This is a fact of salesforce.com development. There is a reason why the deployment rule is 75% coverage, and not 100% coverage. This "wiggle room" exists so that developers can test the majority of their code, since exception handling can be hard to troubleshoot and even harder to test through scripting, since errors are supposed to be the exception, not the rule. The important thing about your test methods is that they verify your code works correctly. Unless you have a way of crafting a record that will fail, the only other method-- which is strongly not recommended-- would be to write a exception built into the actual code you're testing. This involves using
Test.isRunningTest
to set up an arbitrary failure.Sample Code: Original
Sample Code: Modified
globalFlags
would be a class that holds static values for various things. This flag, calledcrashTest
, would be set to true before attempting to update the records. When the trigger sees that it's supposed to crash, it does. You can test your code both ways, once with the flag set, the other with the flag cleared. This will help you cover 100% code.However, this sort of technique isn't recommended for casual optimization of code coverage, because it introduces test behavior in your production code. Such code can later become the source of mystery failures, such as when a test method starts failing because the code though it should crash, or a bug elsewhere somehow causes the trigger to think it's testing and crashes in production. It also increases testing time by requiring developers to actually navigate to the page/record/etc and manually verify that it doesn't crash after code changes.
Of course, one also has to realize that sometimes you can't avoid testing in production code, although the exceptions to the rule of not mixing test code into production are becoming fewer now as testing improves (such as mock callout responses).
One other strategy that does help, though, is to create a class specifically for handling database errors that can be independently tested.
First, you'd change the logic to not use exception handling:
Next, you'd construct your class and method:
To test
globalUtils
, you can forge a test method that will automatically cover the error, such as: