5

I'm working on how to use methods annotated with @TestSetup. I didn't find a way to pass the caseId from the initData method to the methodTest, so I request the case with limit 1. Is that the right way?

// Init Test Data
@TestSetup
static void initData()
{
    Account acc = new Account(Name='Test');
    insert acc;

    Case cse = new Case(AccountId=acc.Id);
    insert cse;
}

// Test method
@IsTest
static void methodTest()
{
    Case cse = [SELECT Id FROM Case LIMIT 1];

    Test.startTest();

    // use cse

    Test.stopTest();
}
6

Yes, you must re-query the data. Sometimes you might use constant strings to pull in, for instance a custom setting:

static final String SETTING_NAME = 'foo';

@TestSetup
static void setup()
{
    insert new MySetting__c(Name=SETTING_NAME);
}

static testMethod void testBar()
{
    MySetting__c relevantSetting = MySetting__c.getInstance('foo');
}

Often, this approach is used for configuration data that will be common to your tests, be it in a Custom Object or Custom Setting.

Similar to your use case, it's a nice convenience when testing an extension.

@TestSetup
static void setup()
{
    insert new Case(/*data*/);
}
static StandardController getController()
{
    return new ApexPages.StandardController([SELECT ... FROM Case LIMIT 1]);
}

static testMethod void testMyExtension_Constructor()
{
    ApexPages.StandardController controller = getController();

    Test.startTest();
        MyExtension extension = new MyExtension(controller);
    Test.stopTest();

    // assert on behavior
}
static testMethod void testSomeMethod()
{
    MyExtension extension = new MyExtension(getController());

    Test.startTest();
        extension.someMethod();
    Test.stopTest();

    // assert on behavior
}
  • 2
    Absolutely missed the custom setting thing, even though I did it myself after knowing how useful it was to create custom settings in @testSetup and then check them every testmethod of my test class. +1 – Mahmood Mar 8 '17 at 13:54
5

It is a correct way. I would, however, like to identify few benefits of @testSetup below

  1. Use this annotation if you want to create test data once and use it in all test methods of your class. Therefore, you don't need to recreate the data again.
  2. Records created in a test setup method are rolled back at the end of test class execution.
  3. @testSetup methods are executed first in the class before any test methods. You may have multiple @testSetup methods in your class, however, their execution order is not guaranteed.

See also:

Test Setup Method Considerations

Test setup methods are supported only with the default data isolation mode for a test class. If the test class or a test method has access to organization data by using the @isTest(SeeAllData=true) annotation, test setup methods aren’t supported in this class.

  • Multiple test setup methods are allowed in a test class, but the order in which they’re executed by the testing framework isn’t guaranteed.
  • You can have only one test setup method per test class.
  • If a fatal error occurs during the execution of a test setup method, such as an exception that’s caused by a DML operation or an assertion failure, the entire test class fails, and no further test methods are executed.
  • If a test setup method calls a non-test method of another class, no code coverage is calculated for the non-test method.
  • 1
    @Mahmood Good answer. Cleared some of my doubts as well...!! – Rohit Mourya Mar 8 '17 at 13:51
  • 1
    You were already halfway there, so I just touched up your citation to hit all of the bullet points. Hope that's okay. – Adrian Larson Mar 8 '17 at 14:20
  • I wish there would've been thumbs up here on SO but nevermind, I got my own. So, here goes .... two thumbs up. – Mahmood Mar 8 '17 at 14:25
  • Another very important consideration is that in a testSetup method, you can execute DML on a setup object and within your unit tests you can execute DML on a non-setup object... and vice-versa. Try that without @testSetup and you'll hit governor limits. – SF1Dev Jun 7 '18 at 22:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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