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

Test Class MIXED_DML_OPERATION
Greetings,
Been pulling out my hair on this one - have a fully functional class/trigger set that performs the following:
Have a "Reports To" and "Reporting VP" lookup fields on the User record. For every Account record I want to have three AccountTeamMembers created, or updated when the Account Owner changes, or if their report to structure should change:
"Sales Rep" (Oppy Owner)
"Sales Manager" (Oppy Owner's Report To) and
"Sales Director" (Oppy Owner's Reporting VP)
Again, the trigger and class are working - I'm struggling with the Test Class. There are three entry points:
1. Account creation - (create the three AccountTeamMembers)
2. Account owner change - (replace the three AccountTeamMembers)
3. User Manager / VP change - (replace the Manager / Director AccountTeamMembers)
Here's the error message / Stack Trace:
Message:
System.DmlException: Update failed. First exception on row 0 with id 005Q0000000LTK4IAO; first error: MIXED_DML_OPERATION, DML operation on setup object is not permitted after you have updated a non-setup object (or vice versa): User, original object: Account: []
Stack Trace:
Class.TestAccountTeamMemberUpdates.testAccountModelATMAssignmentMethods: line 140, column 13 External entry point
I will post my test class in the next message. Thanks for any guidance / assistance!
Pete
@isTest
private class TestAccountTeamMemberUpdates {
static testMethod void testAccountModelATMAssignmentMethods() {
Profile p = [select id from profile where name='Standard User'];
User ManagerA = new User(alias = 'MgrA', ...
User ManagerB = new User(alias = 'MgrB', ...
User ManagerC = new User(alias = 'MgrC', ...
User VPA = new User(alias = 'VPA', email=...
User VPB = new User(alias = 'VPB', email=...
User VPC = new User(alias = 'VPC', email=...
Insert ManagerA;
Insert ManagerB;
Insert ManagerC;
Insert VPA;
Insert VPB;
Insert VPC;
User SalesRepOne = new User(alias = 'SR1'...
Reports_To__c=ManagerA.id,
Reporting_VP__c=VPA.id);
User SalesRepTwo = new User(alias = 'SR2'...
Reports_To__c=ManagerB.id,
Reporting_VP__c=VPB.id);
Insert SalesRepOne;
Insert SalesRepTwo;
// Create new account, default accountteammembers should be created
Account a = new Account(name='Test Account 1', ...
Account b = new Account(name='Test Account 2', ...
System.RunAs(SalesRepOne) {
Insert a;
}
// Test one
AccountTeamMember[] ATMs = [Select TeamMemberRole, UserId
From AccountTeamMember
where AccountId = :a.id];
Boolean RepFound = False;
Boolean MgrFound = False;
Boolean VPFound = False;
for (AccountTeamMember atm : ATMs) {
if (atm.TeamMemberRole == 'Sales Rep') {
RepFound = True;
system.assertequals(SalesRepOne.id,atm.UserId);
}
else if (atm.TeamMemberRole == 'Sales Manager') {
MgrFound = True;
system.assertequals(ManagerA.id, atm.UserId);
}
else if (atm.TeamMemberRole == 'Sales VP') {
VPFound = True;
system.assertequals(VPA.id, atm.userId);
}
else
system.assertequals(1,2); //auto-fail
}
system.assertEquals(RepFound, True);
system.assertequals(MgrFound, True);
system.assertequals(VPFound, True);
// Test one complete
// Reassign account to new owner
a.OwnerId = SalesRepTwo.Id;
update a;
// Test two - ensure accountteammembers correctly re-assigned
ATMs = new AccountTeamMember[0];
ATMs = [Select TeamMemberRole, UserId
From AccountTeamMember
where AccountId = :a.id];
RepFound = False;
MgrFound = False;
VPFound = False;
for (AccountTeamMember atm : ATMs) {
if (atm.TeamMemberRole == 'Sales Rep') {
RepFound = True;
system.assertequals(SalesRepTwo.id,atm.UserId);
}
else if (atm.TeamMemberRole == 'Sales Manager') {
MgrFound = True;
system.assertequals(ManagerB.id, atm.UserId);
}
else if (atm.TeamMemberRole == 'Sales VP') {
VPFound = True;
system.assertequals(VPB.id, atm.userId);
}
else
system.assertequals(1,2); //auto-fail
}
system.assertequals(RepFound, True);
system.assertequals(MgrFound, True);
system.assertequals(VPFound, True);
// Test two complete
// Change the Reports_To and Reporting_VP user field of the account owner
SalesRepTwo.Reports_To__c = ManagerC.id;
SalesRepTwo.Reporting_VP__c = VPC.id;
update SalesRepTwo;
// Test three - ensure accountteammembers correctly re-assigned
ATMs = [Select TeamMemberRole, UserId
From AccountTeamMember
where AccountId = :a.id];
RepFound = False;
MgrFound = False;
VPFound = False;
for (AccountTeamMember atm : ATMs) {
if (atm.TeamMemberRole == 'Sales Rep') {
RepFound = True;
system.assertequals(SalesRepTwo.id,atm.UserId);
}
else if (atm.TeamMemberRole == 'Sales Manager') {
MgrFound = True;
system.assertequals(ManagerC.id, atm.UserId);
}
else if (atm.TeamMemberRole == 'Sales VP') {
VPFound = True;
system.assertequals(VPC.id, atm.userId);
}
else
system.assertequals(1,2); //auto-fail
}
system.assertequals(RepFound, True);
system.assertequals(MgrFound, True);
system.assertequals(VPFound, True);
// Test three complete
}
}
Check out this thread for ideas on how to avoid the MIXED_DML_OPERATION exception in test code - http://boards.developerforce.com/t5/Apex-Code-Development/DML-not-allowed-on-user-in-test-context/m-p/98393
Since User, Profiles are all setup object, you cannot have DML operation on non-setup object immediately after you have performed one on setup object. Please see if you can get it worked using the below steps.
1. Separate the execution context in the test class using Test.startTest() and Test.stopTest().
2. See if you can use System.runAs() to separate the DML operation
I hope this helps!
@isTest
private class SL_Test_TerritoyTriggerAndBatch {
private static final Id ACCOUNT_BROKER_RECORDTYPE = [Select Id, DeveloperName from RecordType where sObjectType='Account' and DeveloperName='Broker' LIMIT 1].Id;
private static testMethod void territorryAssignmentToAccountsByTrigger() {
Account objAccount = new Account(RecordTypeId = ACCOUNT_BROKER_RECORDTYPE, Name = 'Test Acc - 01', ShippingState = 'USA');
insert objAccount;
User usr = [Select id from User where Id = :UserInfo.getUserId()];
System.RunAs(usr)
{
Test.startTest();
insertTestTerritory();
Test.stopTest();
}
}
@future
private static void insertTestTerritory()
{
List<Territory2Type> terriType = [SELECT id, DeveloperName from Territory2Type where DeveloperName = 'Broker_Assignments' LIMIT 1];
Territory2Model terrModel = new Territory2Model();
terrModel .DeveloperName='ModelName'; // required field
terrModel.Name = 'Name'; // required field
insert terrModel ;
Territory2 objTerr = new Territory2(DeveloperName = 'TestTerritory', Territory2ModelId=terrModel.Id, Name='TestTerritory', Territory2TypeId=terriType[0].Id);
insert objTerr;
system.debug('================objTerr===========>>>'+objTerr.Id);
}
}