8

I'd like to create records in @testSetup for my Test Class, to avoid the need to create the same records for each of the methods in the class.

I also need to create both a User record and Custom Settings, Custom object records etc. If I don't use System.runas(u){ to separate the User insert from the other record's insert, it causes the error

MIXED_DML_OPERATION, DML operation on setup object is not permitted after you have updated a non-setup object (or vice versa):

But when I try to combine @testSetup and System.runas(u){ the Developer Console's compiler is telling me that

variable does not exist: u.Id

for line o.OwnerId = u.Id;, in the below. So it looks like the test method can't access the records in the runas section of the code.

Will I have to create the records in the runas section for each test method to avoid this issue?

Note - I've not included the additional test methods in the below because the issue occurs for the first method.

@isTest
public class WE_OppUpdatesTest{

    @testSetup
    static void dataSetup() {

        Profile p1 = [SELECT Id FROM Profile WHERE Name = 'System Administrator - Wex Europe'];

        User[] userList = new User[]{};
            User u = new User();

        u.FirstName = 'Alex';
        u.LastName = 'Sherwood';
        u.Email = 'test@wexeurope.com';
        u.Username = 'astest@wexeurope.com';
        u.Alias = 'astest';
        u.ProfileId = p1.Id;
        u.TimeZoneSidKey    = 'America/Denver';
        u.LocaleSidKey      = 'en_US';
        u.EmailEncodingKey  = 'UTF-8';
        u.LanguageLocaleKey = 'en_US';
        userList.add(u);

        system.debug('u contains ' + u);

        insert userList;

        System.runas(u){

            WEID__c[] csList = new WEID__c[]{};
                WEID__c cs = New WEID__c();
            cs.Name = 'CP Virtual Prepaid MC';
            cs.WEOppId__c = '012700000005qif';

            csList.add(cs);

            insert csList;
            system.debug('csList contains ' + csList);

            //create Target records
            Target__c[] targetList = new Target__c[]{};
                Target__c t = new Target__c();

            t.Name = 'Jun Test';
            t.OwnerId = u.Id;
            t.Salesperson__c = u.Id;
            t.Team__c = 'Virtual Sales EU';
            t.Year_End_Date__c = Date.newInstance(2015,12,31);
            t.Target__c = 100000;
            t.Month_End_Date__c = Date.newInstance(2015,06,30);
            targetList.add(t);

            Target__c t1 = new Target__c();
            t1.Name = 'Jul Test';
            t1.OwnerId = u.Id;
            t1.Salesperson__c = u.Id;
            t1.Team__c = 'Virtual Sales EU';
            t1.Year_End_Date__c = Date.newInstance(2015,12,31);
            t1.Target__c = 100000;
            t1.Month_End_Date__c = Date.newInstance(2015,07,30);
            targetList.add(t1);

            Target__c t2 = new Target__c();
            t2.Name = 'Jul 16 Test';
            t2.OwnerId = u.Id;
            t2.Salesperson__c = u.Id;
            t2.Team__c = 'Virtual Sales EU';
            t2.Year_End_Date__c = Date.newInstance(2016,12,31);
            t2.Target__c = 100000;
            t2.Month_End_Date__c = Date.newInstance(2016,07,30);
            targetList.add(t2);

            insert targetList;

        }
    }

    static testMethod void testOppsPt1(){

        List<Opportunity> immOpportunitys = new List<Opportunity>();
        for (Integer i = 0; i < 1; i++) {

            Opportunity o = new Opportunity();
            o.name = 'Test Opp' + i;
            o.RecordTypeId = '012700000005qif';

/*ERROR >*/ o.OwnerId = u.Id;
            o.Ramp_Profile__c = 'Immediate';
            o.StageName = '1) Suspect';
            o.CloseDate = date.newInstance(2015,06,15);
            o.Monthly_Txn_Revenue_POS__c = 0;
            o.Annual_transaction_volume__c = 1000;
            o.Credit_Limit__c = 100.00;
            o.Date_Credit_Limit_Approved__c = date.newInstance(1901, 01, 01);
            o.Payment_Terms_Days__c = 5;
            o.Billing_Cycle__c = 'Daily';
            o.Annual_Settlement_Value__c = 100.00;
            o.Average_transaction_Value_POS__c = 1.00;

            immOpportunitys.add(o);
        }
        insert immOpportunitys;

    }
}

3 Answers 3

10

The compilation problem is that the definition of u is local to one method and you are trying to reference it in a another method. You can get a local reference to that user to avoid the compilation error like this:

static testMethod void testOppsPt1(){
    User u = [select Id from User where Username = 'astest@wexeurope.com'];
    List<Opportunity> immOpportunitys = new List<Opportunity>();
    for (Integer i = 0; i < 1; i++) {
        ...
}

This keeps all the data creation in the @TestSetup method that is run once only irrespective of how many test methods there are.

PS

Note that by design all static variables are cleared before each test method is executed; querying isthe recommended approach.

1

You can't mix insert of user and other records in one transaction, because user affects visibility of records: reference here

Instead you can do the following. Insert user in @testSetup method. Then before each test method call another helper to insert all required records in the context of a user.

@isTest
public class WE_OppUpdatesTest {

   @testSetup
   static void dataSetup() {
      ...
      insert user;
   }

   static void additionalDataSetup() {
      User u = [SELECT Id FROM User WHERE Name = 'yourname' LIMIT 1];
      System.runAs(u) {
         ... insert all additional records
      }
   }

   static testMethod void test_something() {
      additionalDataSetup();
      ...
   }

   static testMethod void test_somethingElse() {
      additionalDataSetup();
      ...
   }
}
1
  • Thanks for this but I'm still not able to access the user's details >Variable does not exist: u.Id.
    – Alex S
    Jul 6, 2015 at 11:52
1

When data is created in @testSetup, it is available to your tests, but it is not available in the methods until you retrieve it.

Also, the test sets are regenerated for each method.

So, if you create a user in testSetup, you need to use:

User u = [select id from user]; in each test method where you need the user.

You do not really have to specify anything about the user in the select statement since there is only one user created in the test set.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .