1

I am having a dilemma here kind of choosing between two errors:

  1. DML operation on setup object is not permitted after you have updated a non-setup object
  2. UNKNOWN_EXCEPTION, portal account owner must have a role

Below is my unit test code:

account = new Account();
account.Name = 'TestAccount';
account.Trade_Account_Status__c ='Account Customer';
account.BillingStreet  = 'FakeStreet';
account.BillingCity = 'Fake City';
account.BillingState = 'Fake State';
account.BillingPostalCode = 'Fake PostalCode';
account.CanOrderJudgment__c = true;
insert account;

contact = Test_CommonData.CreateContact('Contact', account.Id);

user = Test_CommonData.CreateUser(contact.Id);

And in Test_CommonData class:

public static User CreateUser(Id contactId){
    Profile profileObj = [select Id, UserLicense.Name, UserLicenseId from Profile where Name = 'Cortex Standard Customer Monthly - Customer Portal' limit 1];
    UserRole usrrole = [Select Id, name From UserRole Where PortalType = 'None' limit 1];
    User userObj = new User();
    userObj.LastName='Test';
    userObj.FirstName='User';
    userObj.city='Brisbane';
    userObj.Street='Test st';
    userObj.State='QLD';
    userObj.PostalCode='4000';
    userObj.TimeZoneSidKey = 'Australia/Brisbane';
    userObj.Username = 'test121@test.com';
    userObj.Email = 'test121@test.com';
    userObj.CommunityNickname='test121';
    userObj.Alias='t100';
    userObj.LocaleSidKey = 'en_GB';
    userObj.EmailEncodingKey = 'UTF-8';
    userObj.LanguageLocaleKey = 'en_US';
    userObj.isActive = true;
    userObj.ProfileId = profileObj.Id;
    userObj.IsPortalSelfRegistered = true;
    userObj.contactId = contactId;
    userObj.Office_Server_Storage_Location__c = 'C';
    userObj.UserRoleId = null;
    insert userObj;

    return userObj;
}

public static Contact CreateContact(String contactName,Id accountId){

    Contact contactObj = new Contact();
    contactObj.Contact_Type__c = 'Client';
    contactObj.Lastname = contactName;
    contactObj.AccountId = accountId;
    contactObj.Online_Order_Jurisdiction__c = 'SUP-DJAG;CCJ-DJAG';
    contactObj.Audio_Upload_Jurisdiction__c  = 'PRIVATE';
    contactObj.Show_AudioUpload_Form__c = true;
    contactObj.Show_AFP_Form__c = true;
    contactObj.Test_AudioUpload__c = true;
    insert contactObj;

    return contactObj;
}

If I am assigning the userObj's UserRoleId to be null, I am getting portal account owner must have a role error. And if I am assigning the it to be usrrole.Id, I am getting Mixed DML exception.

How should I walk around this issue. I have read all the posts about the previous two issues but doesn't seem to help though.

2 Answers 2

4

There are two common strategies which allow you to cross the transaction boundary, hence avoiding the first error:

  1. Use system.runAs(userRecord) (in a test environment)
  2. Use a @future method (in a non-test environment)

It looks like you are hitting the error only when creating a test User record, so use the former:

// set up other data
system.runAs(SYS_ADMIN)
{
    // insert User
}
1
  • It sounds silly but when I have this happen I wrap the run as in my own user. OP keep in mind that whatever user you use they will be the owner of records just like they were logged in and running it. A trick for the ages for sure.....
    – Eric
    Apr 18, 2017 at 14:50
2

To prevent mixed DML exception, you can take this approach.

Use @testsetup to create Account and Contact records.

@testSetup
    static void allTheDataForThisTestClass() {
     account = new Account();
    account.Name = 'TestAccount';
    account.Trade_Account_Status__c ='Account Customer';
    account.BillingStreet  = 'FakeStreet';
    account.BillingCity = 'Fake City';
    account.BillingState = 'Fake State';
    account.BillingPostalCode = 'Fake PostalCode';
    account.CanOrderJudgment__c = true;
    insert account;

    contact = Test_CommonData.CreateContact('Contact', account.Id);
}

And in separate testMethod, create the portal user.

static testMethod void unitTestCreateMoreData() {
    Contact con = [SELECT Id From Contact WHERE Lastname = 'Contact];

    System.runAs('<provide userId >')
    {
        user = Test_CommonData.CreateUser(con.Id);

    }

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.