Why do we have @TestSetup, when the result is as equal to not using them?

The scenario that @testSetup solves is simple.

Say you have a class that has three methods, all of which take a contact, and do different things. You might write a test for it like this:

@isTest public class ContactRejiggererTest {
    @isTest public static test_contact_rennovate() {
        Contact con = new Contact(FirstName='Al', LastName='Roker',Phone='612-555-1212');
        insert con;

        // query the contact for a Formula
        con = [SELECT FirstName,LastName,Favorite_Book_Formula__c FROM Contact LIMIT 1][0];
        System.assertEquals(null,Favorite_Book_Formula__c);
        ContactRejiggerer.rennovate(con);
        System.assertEquals('Building Bridges',Favorite_Book_Formula__c);
    }

    @isTest public static test_contact_mediate() {
        Contact con = new Contact(FirstName='Al', LastName='Roker',Phone='612-555-1212');
        insert con;

        // query the contact for a Formula
        con = [SELECT FirstName,LastName,Favorite_Book_Formula__c FROM Contact LIMIT 1][0];
        System.assertEquals(null,Favorite_Book_Formula__c);
        ContactRejiggerer.mediate(con);
        System.assertEquals('Zen and Motorcycles',Favorite_Book_Formula__c);
    }

    @isTest public static test_contact_deviate() {
        Contact con = new Contact(FirstName='Al', LastName='Roker',Phone='612-555-1212');
        insert con;

        // query the contact for a Formula
        con = [SELECT FirstName,LastName,Favorite_Book_Formula__c FROM Contact LIMIT 1][0];
        System.assertEquals(null,Favorite_Book_Formula__c);
        ContactRejiggerer.deviate(con);
        System.assertEquals('The Anarchist's Cookbook',Favorite_Book_Formula__c);
    }
}

There's a lot of code re-use here! We can solve that with a @testSetup!

@isTest public class ContactRejiggererTest {
   @testSetup public static createAl() {
        Contact con = new Contact(FirstName='Al', LastName='Roker',Phone='612-555-1212');
        insert con;
   }

    @isTest public static test_contact_rennovate() {
        con = [SELECT FirstName,LastName,Favorite_Book_Formula__c FROM Contact LIMIT 1][0];
        System.assertEquals(null,Favorite_Book_Formula__c);
        ContactRejiggerer.rennovate(con);
        System.assertEquals('Building Bridges',Favorite_Book_Formula__c);
    }

    @isTest public static test_contact_mediate() {
        con = [SELECT FirstName,LastName,Favorite_Book_Formula__c FROM Contact LIMIT 1][0];
        System.assertEquals(null,Favorite_Book_Formula__c);
        ContactRejiggerer.mediate(con);
        System.assertEquals('Zen and Motorcycles',Favorite_Book_Formula__c);
    }

    @isTest public static test_contact_deviate() {
        con = [SELECT FirstName,LastName,Favorite_Book_Formula__c FROM Contact LIMIT 1][0];
        System.assertEquals(null,Favorite_Book_Formula__c);
        ContactRejiggerer.deviate(con);
        System.assertEquals('The Anarchist's Cookbook',Favorite_Book_Formula__c);
    }
}

The contact gets rolled back to it's initial state after each test method.


There is also an undocumented limit to the total number of records that can be inserted when running unit tests. Moving to @TestSetup solved this problem for us in our most recent large project.

Tags:

Apex

Unit Test