Discussions
- General Development
- Schema Development
- Apex Code Development
- Visualforce Development
- Formulas & Validation Rules
- Security
- Mobile
- Force.com Sites & Site.com
- Chatter Development
- Java Development
- .NET Development
- Perl, PHP, Python & Ruby
- Desktop Integration
- APIs and Integrations
- Visual Workflow
- Apple, Mac and OS X
- VB and Office Development
- AppExchange Directory & Packaging
- Salesforce Labs & Open Source Projects
- Other Salesforce Applications
- Jobs Board
- Force.com Discussion Boards
- :
- Developer Boards for Force.com and Database.com
- :
- Apex Code Development
- :
- Unit Test Failing Because of Maximum Trigger Depth...
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic to the Top
- Bookmark
- Subscribe
- Printer Friendly Page
Unit Test Failing Because of Maximum Trigger Depth Exceeding
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
12-07-2012 11:02 AM
I'm trying to write a unit test for a trigger that captures the OwnerID of an Opportunity, and then populates a "Owner Details" field (giving us access to their entire user record) and a "Sales Manager" field (which is the user's manager).
I'm at 73% coverage, but the part that is not covered is the after update when the Opportunity Owner has changed. I've written into my test a scenario when the Opp Owner changes, but I'm getting the following error message:
System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, CopyOwnerInformation: execution of AfterUpdate caused by: System.DmlException: Update failed. First exception on row 0 with id 006S0000006jI1iIAE; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, CopyOwnerInformation: maximum trigger depth exceeded Opportunity trigger event AfterUpdate for [006S0000006jI1i] Opportunity trigger event AfterUpdate for [006S0000006jI1i] Opportunity trigger event AfterUpdate for [006S0000006jI1i] Opportunity trigger event AfterUpdate for [006S0000006jI1i] Opportunity trigger event AfterUpdate for [006S0000006jI1i] Opportunity trigger event AfterUpdate for [006S0000006jI1i] Opportunity trigger event AfterUpdate for [006S0000006jI1i] Opportunity trigger event AfterUpdate for [006S0000006jI1i] Opportunity trigger event AfterUpdate for [006S0000006jI1i] Opportunity trigger event AfterUpdate for [006S0000006jI1i] Opportunity trigger event AfterUpdate for [006S0000006jI1i] Opportunity trigger event AfterUpdate for [006S0000006jI1i] Opportunity trigger event AfterUpdate for [006S0000006jI1i] Opportunity trigger event AfterUpdate for [006S0000006jI1i] Opportunity trigger event AfterUpdate for [006S0000006jI1i] Opportunity trigger event AfterUpdate for [006S0000006jI1i]: [] Trigger.CopyOwnerInformation: line 40, column 1: []
Here is the relevant code from my trigger. This is the part that I am trying to cover:
//Insert new owner details ID if it has changed
if(opp.Owner_Details__c == null || (opp.OwnerId != oldopp.OwnerID)){
List<Opportunity> OppsWithNewOwner = [SELECT ID, OwnerID, Owner_Details__c FROM Opportunity WHERE id in:trigger.new];
for (Integer i=0; i<OppsWithNewOwner.size(); i++){
OppswithNewOwner[i].Owner_Details__c = OppsWithNewOwner[i].OwnerID;}
update OppsWithNewOwner;
}
And here is my test class:
@isTest
private class Test_CopyOwnerInformation{
static testMethod void CopyOwnerInformation(){
//set up test records
User user1 = new User();
user1.firstname = 'Test User 1 First Name';
user1.lastname = 'Test User 1 Last Name';
user1.alias = 'user1';
user1.email = 'testuser@unittest.com';
user1.EmailEncodingKey = 'ISO-8859-1';
user1.username = 'testuser1@unittest.com';
user1.TimeZoneSidKey = 'America/Chicago';
user1.LocaleSidKey = 'en_US';
user1.ProfileId = '00e70000000sP2v';
user1.LanguageLocaleKey = 'en_US';
insert user1;
User manager2 = new User();
manager2.firstname = 'Test Manager 2 First Name';
manager2.lastname = 'Test Manager 2 Last Name';
manager2.alias = 'mgr2';
manager2.email = 'testmanager@unittest.com';
manager2.EmailEncodingKey = 'ISO-8859-1';
manager2.username = 'testmanager2@unittest.com';
manager2.TimeZoneSidKey = 'America/Chicago';
manager2.LocaleSidKey = 'en_US';
manager2.ProfileId = '00e70000000sP2v';
manager2.LanguageLocaleKey = 'en_US';
insert manager2;
User user2 = new User();
user2.firstname = 'Test User 2 First Name';
user2.lastname = 'Test User 2 Last Name';
user2.alias = 'user2';
user2.email = 'testuser@unittest.com';
user2.EmailEncodingKey = 'ISO-8859-1';
user2.username = 'testuser2@unittest.com';
user2.manager = manager2;
user2.TimeZoneSidKey = 'America/Chicago';
user2.LocaleSidKey = 'en_US';
user2.ProfileId = '00e70000000sP2v';
user2.LanguageLocaleKey = 'en_US';
insert user2;
Account account = new Account();
account.Name = 'Test Account';
account.OwnerID = user1.id;
account.web_site__c = 'test.com';
account.industry = 'Entertainment';
account.type = 'Advertiser';
insert account;
Opportunity opportunity = new Opportunity();
opportunity.AccountId = account.Id;
opportunity.OwnerID = account.OwnerId;
opportunity.Name = 'Test Opportunity';
opportunity.StageName = 'Active';
opportunity.CloseDate = System.today();
opportunity.Amount = 1000.00;
opportunity.Type = 'New Client';
//test
test.startTest();
insert opportunity;
//Validate that the Owner Details field was updated.
opportunity = [SELECT OwnerId, Owner_Details__c, Owner_Details__r.ManagerID, SalesManager__c FROM Opportunity WHERE id = :opportunity.id];
System.assertEquals(opportunity.OwnerId, opportunity.Owner_Details__c);
System.assertEquals(opportunity.SalesManager__c, Opportunity.Owner_Details__r.ManagerID);
//Test that the Owner Details changes with an Opp Owner Change
opportunity.OwnerId = user2.ID;
update opportunity;
test.stopTest();
//Validate that the Owner Details and Manager fields were updated.
opportunity = [SELECT OwnerID, Owner_Details__c, Owner_Details__r.ManagerID, SalesManager__c FROM Opportunity WHERE id = :opportunity.id];
System.assertEquals(opportunity.Owner_Details__c, user2.Id);
System.assertEquals(opportunity.SalesManager__c, user2.Manager.Id);
}
}Thank you for the help!
Solved! Go to Solution.
Re: Unit Test Failing Because of Maximum Trigger Depth Exceeding
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
12-07-2012 01:54 PM
I see a few issues with your trigger. Can you post the entire code so this can be resolved?
Certified Salesforce Developer
Check out my blog. http://andrewwilkinsonsf.blogspot.com/
Re: Unit Test Failing Because of Maximum Trigger Depth Exceeding
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
12-07-2012 02:02 PM
But a few things that need to be resolved are recursion(which could be satsfied without adding an additional update to this field. The portion displayed in this trigger should occur before update and not after update since it is the same object that is being updated. This would solve the recursion. Also, I would like to see if there are other ways to optimize this trigger. I noticed you are running DML's on individual statements instead of in bulk. This can cause issues and failures as well. Please post your code and I can resolve these for you and give you some tips.
Certified Salesforce Developer
Check out my blog. http://andrewwilkinsonsf.blogspot.com/
Re: Unit Test Failing Because of Maximum Trigger Depth Exceeding
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
12-07-2012 02:05 PM
Hi Andrew - thanks so much for your help! I'm new to Apex and have never done any coding before, so I really appreciate all of the tips I can get.
Here is the entire trigger:
trigger CopyOwnerInformation on Opportunity (before Insert, after Update) {
//------------Before Insert----------------------
//Copy Owner to Owner Details Field
if(Trigger.isBefore && Trigger.isInsert){
for (Opportunity x: Trigger.New) {x.Owner_Details__c=x.OwnerID;
}
}
//-------------After Update----------------------------------
//compare old and new record to see if the Sales Manager field has changed
if(Trigger.isAfter && Trigger.isUpdate){
//create map to compare old Opp values
for (Opportunity opp: trigger.new) {
Opportunity oldopp = Trigger.oldMap.get(opp.ID);
//Insert new owner details ID if it has changed
if(opp.Owner_Details__c == null || (opp.OwnerId != oldopp.OwnerID)){
List<Opportunity> OppsWithNewOwner = [SELECT ID, OwnerID, Owner_Details__c FROM Opportunity WHERE id in:trigger.new];
for (Integer i=0; i<OppsWithNewOwner.size(); i++){
OppswithNewOwner[i].Owner_Details__c = OppsWithNewOwner[i].OwnerID;}
update OppsWithNewOwner;
}
//Update Sales Manager Field
if(opp.SalesManager__c == null || (opp.SalesManagerID__c != oldopp.SalesManagerID__c)){
List<Opportunity> UpdateOpps = [SELECT Id, SalesManager__c, SalesManagerID__c
FROM Opportunity
WHERE Id in: trigger.new];
// for records that require an update, copy Sales Manager ID to Sales Manager field
for (Integer i=0; i<UpdateOpps.size(); i++){
UpdateOpps[i].SalesManager__c = UpdateOpps[i].SalesManagerID__c;
}
Update UpdateOpps;
}
}
} // end of after update
} // end of trigger
Re: Unit Test Failing Because of Maximum Trigger Depth Exceeding
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
12-07-2012 02:10 PM
I'm sure there is a ton to fix in the trigger, but I should also mention that I haven't run into the max trigger depth error when making changes in the UI. It's only occuring in my test method.
Thanks again!
Re: Unit Test Failing Because of Maximum Trigger Depth Exceeding
[ Edited ]- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
12-07-2012 02:18 PM - edited 12-07-2012 02:19 PM
Made a few changes. I commented out the after code and turned it into a before code.
trigger CopyOwnerInformation on Opportunity (before update, before Insert, after Update) {
//------------Before Insert----------------------
//Copy Owner to Owner Details Field
if(Trigger.isBefore && Trigger.isInsert){
for (Opportunity x: Trigger.New) {x.Owner_Details__c=x.OwnerID;
}
}
//-------------Before Update---------------------------------
if(Trigger.isbefore && Trigger.isUpdate){
for(Opportunity o : Trigger.new){
if(o.Owner_Details__c == null || (o.OwnerId != Trigger.oldMap.get(o.Id).OwnerId)){
o.Owner_Details__c = o.OwnerId;
}
if(o.SalesManager__c == null || (o.SalesManagerID__c != Trigger.oldMap.get(o.Id).SalesManagerID__c)){
o.SalesManager__c = o.SalesManagerID__c;
}
}
}
//-------------After Update----------------------------------
//compare old and new record to see if the Sales Manager field has changed
/*if(Trigger.isAfter && Trigger.isUpdate){
//create map to compare old Opp values
for (Opportunity opp: trigger.new) {
Opportunity oldopp = Trigger.oldMap.get(opp.ID);
//Insert new owner details ID if it has changed
if(opp.Owner_Details__c == null || (opp.OwnerId != oldopp.OwnerID)){
List<Opportunity> OppsWithNewOwner = [SELECT ID, OwnerID, Owner_Details__c FROM Opportunity WHERE id in:trigger.new];
for (Integer i=0; i<OppsWithNewOwner.size(); i++){
OppswithNewOwner[i].Owner_Details__c = OppsWithNewOwner[i].OwnerID;}
update OppsWithNewOwner;
}
//Update Sales Manager Field
if(opp.SalesManager__c == null || (opp.SalesManagerID__c != oldopp.SalesManagerID__c)){
List<Opportunity> UpdateOpps = [SELECT Id, SalesManager__c, SalesManagerID__c
FROM Opportunity
WHERE Id in: trigger.new];
// for records that require an update, copy Sales Manager ID to Sales Manager field
for (Integer i=0; i<UpdateOpps.size(); i++){
UpdateOpps[i].SalesManager__c = UpdateOpps[i].SalesManagerID__c;
}
Update UpdateOpps;
}
}
}*/ // end of after update
} // end of triggerThis can all be done with a before update. But I am pretty sure you don't even need the trigger and this should be done in a workflow rule.
Certified Salesforce Developer
Check out my blog. http://andrewwilkinsonsf.blogspot.com/
Re: Unit Test Failing Because of Maximum Trigger Depth Exceeding
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
12-07-2012 02:28 PM
Hi Andrew - thank you again for your help! I'll test this now and let you know how it goes and after mark it as a solution.
The reason this wouldn't work with workflow rules was that the SalesManager__c and Owner_Details__c fields are user lookup fields, and field updates with look up fields are pretty restrictive. You can just choose a specific person, not update it with an ID.
Re: Unit Test Failing Because of Maximum Trigger Depth Exceeding
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
12-07-2012 03:13 PM
I'm running into a bit of trouble. The SalesManagerID__c field is a formula that uses the Owner_Details__c field to get the user's manager's ID. However, with the way the trigger is set up, the Sales Manager ID that is being grabbed to update SalesManager__c is the value from before the trigger firing. It's updating to match new Owner_Details__c field.
I suppose I could create a Sales Manager ID field that is not a formula and update that in the trigger as well, but is there a way that does not involve making a new field?
I tried the following, but now it's not updating the Sales Manager field at all.
if(Trigger.isbefore && Trigger.isUpdate){
for(Opportunity o : Trigger.new){
if (o.Owner_Details__c == null || (o.OwnerID != Trigger.oldMap.get(o.ID).OwnerID)){
o.Owner_Details__c = o.OwnerId;
if (o.SalesManager__c == null || (o.SalesManagerID__c != Trigger.oldMap.get(o.ID).SalesManagerID__c)){
o.SalesManager__c = Trigger.newMap.get(o.ID).SalesManagerId__c;
}
}
}
}
Re: Unit Test Failing Because of Maximum Trigger Depth Exceeding
[ Edited ]- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
12-07-2012 03:18 PM - edited 12-07-2012 03:31 PM
Formula fields are tricky. So you would need to replicate that field formula in the trigger
Certified Salesforce Developer
Check out my blog. http://andrewwilkinsonsf.blogspot.com/
Re: Unit Test Failing Because of Maximum Trigger Depth Exceeding
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
12-07-2012 05:19 PM
This is what the original formula was: Owner_Details__r.ManagerId
Here is what I did to try to replicate this in the trigger:
trigger CopyOwnerInformation on Opportunity (before Insert, before update) {
//------------Before Insert----------------------
//Copy Owner to Owner Details Field
if(Trigger.isBefore && Trigger.isInsert){
for (Opportunity x: Trigger.New) {
x.Owner_Details__c=x.OwnerID;
}
}
//----------------Before Update------------------------------
if(Trigger.isbefore && Trigger.isUpdate){
for(Opportunity o : Trigger.new){
o.Owner_Details__c = o.OwnerId;
system.debug('********* Owner Details ID**********' + o.Owner_Details__c);
o.SalesManagerIDv2__c = o.Owner_Details__r.ManagerID;
system.debug('********* Owner Details ID + Sales Manager Id **********' + o.Owner_Details__c+ ' '
+ o.SalesManagerIDv2__c);
o.SalesManager__c = o.SalesManagerIDv2__c;
The debug log shows that Owner Details updates properly, but the SalesManagerIDv2 field is null (even though the user has a manager on their user record). Any idea what I'm doing wrong?
Am I better of just making this an "After Update" trigger again? I understand the reasoning for avoiding that, but it was working (with the exception of the Unit Test)

