+ Start a Discussion
Roger WickiRoger Wicki 

AddError does not seem to work in Test

Hi community

I am writing a test class for my handler, which checks if the user is allowed to perform CRUD on some child objects if the parent object is in a specific state. I am struggling with one test method only, the one which adds an error to the sObject. Here is my code:

// Maps from OpportunityId to different sObjects like Attachment, OpportunityLineItem, etc.
@TestVisible private map<Id, sObject> parentIdChildMap;
// Opportunity Ids for which no CRUD on child objects are allowed
@TestVisible private set<Id> lockedOpportunitiesIds;
...
...
/*
*	Adds an error to all sObjects which are attached to a yes Opportunity
*/
@TestVisible private void invalidateSObjects() {
	for ( Id opportunityId : lockOpportunitiesIds ) {
		system.debug('Adding Error for object ' +parentIdChildMap.get(opportunityId));
		parentIdChildMap.get(opportunityId).addError('This '
        + parentIdChildMap.get(opportunityId).getSObjectType().getDescribe().getLabel()
		+ '\'s Opportunity is already in a stage where you can no longer add, edit or remove it.');
		system.debug('Error added');
	}
}
...
And my test method:
private static testMethod void testInvalidateSObjects() {
    ArcUtil.setSkipForTest(true);
	Account parent = new Account(Name = 'Test Parent', Type = 'Manufacturer');
	insert parent;
	
	OpportunityStageProtection osp = new OpportunityStageProtection();
	osp.setLockOpportunitiesIds(new set<Id>{'006000000012345'});
	osp.setParentChildMap(new map<Id, sObject>{'006000000012345' => new Attachment(ParentId = parent.Id, Name = 'testSObject', Body = Blob.valueOf('Test Body'))});
	osp.invalidateSObjects();
	insert osp.parentIdChildMap.values();
    ArcUtil.setSkipForTest(false);
}
I expected my code to throw an error upon insertion but it does not. As you might have guessed, the fix typed ID "006000000012345" is a fake Opportunity ID. But in the end it should not matter. The test itself should not cause my trigger and handler to run (I actually forbid that with ArcUtil.setSkipForTest(true)), it should merely recognize that I already added an error to the Attachment record and prevent insertion. My debug log clearly states that the lines for adding the error have run through, so the addError line clearly was executed.

Do you have any insights on that? I want to test my methods locally possible without the use of too many DML that cause triggers to fire on every single object I need to insert & update for tests... Do you know of another way to check if an error has been added? Like sObject.getErrors() or something? There's no such thing on the sObject description though :/
UC InnovationUC Innovation
The AddError() function won't throw any exceptions.  It just provides an error message to be shown in the VF page.  You can do something like this to in your test class instead:

http://www.infallibletechie.com/2015/10/how-to-cover-adderror-in-trigger-in.html
Roger WickiRoger Wicki
I found a source on StackExchange (http://salesforce.stackexchange.com/questions/32375/how-to-adderror-in-class-and-how-to-test-it) that stated addError() only works with data from the trigger context. So one can not use it on any data that is queried or manually created within a class.

While in the end my handler will work on trigger data, it is hard to actually test this way without making testing slower than required. I will try the Database.insert statement though as there might be more information saved than on a simple insert statement.