You need to sign in to do that
Don't have an account?
Testing Undelete Triggers?
Hi All,
I'm new here, so hopefully I don't say anything too silly/dumb.
I am having a problem with testing an undelete trigger I have written. I am getting an DMLException for de-referenfing a null object when trying to test my undelete trigger. It may be that I am misunderstanding completely how testing of Apex undeletes should work...
My basic requirements are that I have an order, and I have a field on that order called Needs Attn. I need to set this field to True whenever the order is updated or when it is undeleted.
My Trigger in JGOrderUpdate.trigger:
trigger JGOrderUpdate on JG__Order__c (before update, after undelete) { for(JG__Order__c o : Trigger.new) { JG__Order__c old = Trigger.oldMap.get(o.Id); if(!old.Needs_Attn__c) o.Needs_Attn__c = true; } }
My Test Code JGTriggerTests.cls :
// create a order JG__Order__c o = new JG__Order__c(); o.Needs_Attn__c = false; insert o; // this kicks off the before update trigger for orders update o; // Confirms Actual update tests for orders JG__Order__c test_o = [Select Id, Needs_Attn__c From JG__Order__c Where Id =: o.Id]; System.assert(test_o.Needs_Attn__c); // now we set the order back to needing attention false o.Needs_Attn__c = false; // now we delete the order so we can undelete it to make sure when we undelete it actually // changes to Needs_Attn__c == True delete o; // this kicks off the undelete trigger code // HAVING THE PROBLEM ON THE LINE BELOW undelete o; // did the trigger run properly System.assert(test_so.Needs_Attn__c);
Here's the error i get on the line above with "undelete o;"
Description Resource Path Location Type System.DmlException: Undelete failed. first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, JGOrderUpdate: execution of AfterUndelete caused by: System.NullPointerException: Attempt to de-reference a null object Trigger.JGOrderUpdate: line 3, column 38: [] JGTriggerTests.cls Description Resource Path Location TypeSystem.DmlException: Undelete failed. first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, JGOrderUpdate: execution of AfterUndelete caused by: System.NullPointerException: Attempt to de-reference a null object Trigger.JGOrderUpdate: line 3, column 38: [] JGTriggerTests.cls
Any help would be greatly appreciated!
Thanks
j
Sorry chnge this from
to
dont use o.Need_Attn__c
All Answers
For undelete triggers, only Trigger.new is usable. Trigger.old doesn't exist in the context of an undelete trigger.
so should i separate my undelete trigger from my update trigger?
also, how do you test an undelete trigger if you can't do something like this:
insert object_x;
delete object_x;
undelete object_x;
Because that last line causes the dml exception...
First, it's not the undelete line in your unit test that's causing the error. The undelete starts out just fine, but it's the fact that your undelete trigger is attempting to access Trigger.old that's causing the problem.
Second, if you want to change the value of a field, you have to make the change in Trigger.new, not in Trigger.old. Trigger.old reflects what used to be in the database before the change started. In a Before trigger, Trigger.new reflects what will be written to the database right after the Before trigger finishes. So make your change to Trigger.new, not Trigger.old.
Third, let's think about what you want your trigger to do. It looks like you're saying, "When a JG Order record is updated, the value of Needs Attn is false, set it to true." Is that what you really mean to be saying? Frankly, it seems a little odd -- why wouldn't you just say, "Set Needs Attn to true" and omit the IF statement? Can you simplify the code to remove any reference to Trigger.old?
Finally, unless you omit the IF statement as mentioned above, you may very well need to separate the Update and Undelete logic into two separate branches. Think about what you want the trigger to do, write it out fully in English (rather than in code), and only after that, translate it into code.
Hope that helps--
MJ.
Hi,
Your trigger is on "after undelete". So in after triggers you cannot change any value from the OldMap.
In your code you are trying to get the values from the OldMap. That is causing this exception.
In order to test your "after undelete" trigger you can seperate the "Before" and "After" triggers logic.
In your "after undelete" trigger logic, you can add following things.
if(isTrigger.undelete)
{
}
That should work for you!!
No in undelete trigger trigger.new is available but you can not update it. Your trigger should be like this
Wow, you guys are amazing. I was worried there were going to be crickets.
So I am trying out both possible solutions of splitting it up or keeping it together. Honestly, I like the idea of keeping them together (not sure why though).
One quesiton for Mr. Sharma...
On this line:
My IDE won't let me save the file because it says the variable id does not exist. It puts a red x next to the line above. But I think I know what you were trying to do something like this:
Does this do the same thing or are you doing something entirely different? My IDE allows me to save it this way... weird.
Thanks again!
j
Yes I wanted to do the same , actualy here on provding solution I can not compile it so some times these small typing mistakes do happen, happy that my solution worked for you. :)
What i suggested was
this is same what you updated it
just differnet way of adding it to list.
Hey Guys,
Again thanks for the for the replies. I decided to separate the triggers. So Now I have these two:
The before update:
And the after undelete:
Alright, and my original problem persits. I cannot test the undelete because of the same exact DML Exception as listed the first time.
Here is my test code:
I have removed any form of Trigger old from the undelete as everyone has suggested, but I still have the same DML Error.
Is there anything else you guys can see with my code causing the undelete o; to fail? is this even the correct way to test an undelete. There seems to be much less documenation on undeletes out there than updates and inserts for triggers.
Thanks Again,
j
This is so odd...
If I delete the line above the delete o; line then the test case runs fine. No DML Exception...
Can anyone explain why this is happening?
To add to this problem... I now have only 33% test coverage on my undelete trigger. It is saying these two lines lack test cases:
I understand there is a learning curve and I appreciate any help. But it seems like based on my previous test code (with the update o;) I would have had 100% test coverage, but now in order to even run the test case, I have to remove that and have less coverage.
Any ideas?
j
Try this if you don't want to separete
If you want seperate then chnge your delete like this
My original problem is still the same. I cannot test this code.
Unfortunately, I cannot mark any of these as solutions either, becase none of these work inside IDE. The IDE won't accept the code whether it is a syntax or logical error. I posted the reasons why the IDE won't accept it earlier.
Here is how I got it to do what you are trying to do, but still this causes errors when I try to test the code....
So, I am stuck. How do you test an undelete without getting the DML Exception?
I have sent my test code, errors I got previously. They are all still the same no matter what solution I use in this thread...
Thanks for any help.
j
Please use this for undelete trigger
This should work
Unfortunately, this does not work
Here is the error I get:
Description Resource Path Location TypeSave error: Invalid field initializer: o.Needs_Attn__c JGOrderAfterUndelete.trigger /JGTest/src/triggers line 5 Force.com save problem
The error appears as a red x next to this line in your code:
Sorry chnge this from
to
dont use o.Need_Attn__c
Very nice, finally it worked. 100% test coverage!!!
Wow that was fun. On to the next trigger.
Please don't look only for test coverage, cover all posible scenarios and test fr bulk data as well.