function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Frans Flippo 14Frans Flippo 14 

Test data isolation not working

I've got a test class that starts:
 
@IsTest
private class WarehouseCalloutServiceTest {
    
    @TestSetup
    public static void setup() {
        List<Product2> existingProducts = [ SELECT Id, StockKeepingUnit FROM Product2 ];
        System.debug('Existing products:');
        for (Product2 product : existingProducts) {
            System.debug('- ' + product);
        }
        
        // Insert equipment
        List<Product2> equipmentList = new List<Product2>();
        // Maintenance cycle changes
        equipmentList.add(new Product2(
            Name = 'Generator 1000 kW',
            Cost__c = 5000,
            Current_Inventory__c = 6,
            StockKeepingUnit  = '100003',
            Lifespan_Months__c = 0,
            Maintenance_Cycle__c = 730,
            Replacement_Part__c = false
        ));
        // No changes
        equipmentList.add(new Product2(
            Name = 'Cooling Fan',
            Cost__c = 300,
            Current_Inventory__c = 183,
            StockKeepingUnit  = '100004',
            Lifespan_Months__c = 0,
            Maintenance_Cycle__c = 0,
            Replacement_Part__c = true
        ));
        // Quantity changes
        equipmentList.add(new Product2(
            Name = 'Fuse 20A',
            Cost__c = 22,
            Current_Inventory__c = 144,
            StockKeepingUnit  = '100005',
            Lifespan_Months__c = 0,
            Maintenance_Cycle__c = 0,
            Replacement_Part__c = true
        ));
        // SKU 100006 doesn't exist yet
        System.debug('Inserting ' + equipmentList);
        insert equipmentList;        
    }

The loop that prints out existing products prints nothing.
However, the insert fails with an error: 
System.DmlException: Insert failed. First exception on row 0; first error: DUPLICATE_VALUE, A Equipment with this SKU already exists.: [StockKeepingUnit]

It's true that such a record already exists in my org. However, the tests are supposed to not see that data. So why is this insert failing?
AnudeepAnudeep (Salesforce Developers) 
As far as I know, you are experiencing this because of the SOQL query you have which is querying records from the database and the rest of the code is based on that. 

Per the documentation, the following example shows how to create test records once and then access them in multiple test methods.
 
@isTest
private class CommonTestSetup {
 
    @testSetup static void setup() {
        // Create common test accounts
        List<Account> testAccts = new List<Account>();
        for(Integer i=0;i<2;i++) {
            testAccts.add(new Account(Name = 'TestAcct'+i));
        }
        insert testAccts;        
    }
    
    @isTest static void testMethod1() {
        // Get the first test account by using a SOQL query
        Account acct = [SELECT Id FROM Account WHERE Name='TestAcct0' LIMIT 1];
        // Modify first account
        acct.Phone = '555-1212';
        // This update is local to this test method only.
        update acct;
        
        // Delete second account
        Account acct2 = [SELECT Id FROM Account WHERE Name='TestAcct1' LIMIT 1];
        // This deletion is local to this test method only.
        delete acct2;
        
        // Perform some testing
    }
 
    @isTest static void testMethod2() {
        // The changes made by testMethod1() are rolled back and 
        // are not visible to this test method.        
        // Get the first account by using a SOQL query
        Account acct = [SELECT Phone FROM Account WHERE Name='TestAcct0' LIMIT 1];
        // Verify that test account created by test setup method is unaltered.
        System.assertEquals(null, acct.Phone);
        
        // Get the second account by using a SOQL query
        Account acct2 = [SELECT Id FROM Account WHERE Name='TestAcct1' LIMIT 1];
        // Verify test account created by test setup method is unaltered.
        System.assertNotEquals(null, acct2);
        
        // Perform some testing
    }
 
}

 
Frans Flippo 14Frans Flippo 14
Hi Anudeep,

As you can see in the code fragment I posted, using @TestSetup to set up test data is exactly what I'm doing.

But the test is already failing there: it refuses to insert even the first Product2 record in the list because of a supposed duplicate value; but the test shouldn't be seeing any data already in Product2, so that means a single insert should never fail for duplication reasons: you can't have a duplicate if there's only one record.

It seems that this data isolation for tests isn't as good as it should be.

Anyone else that can shed some light on this?

Thanks,
Frans
leonardokipperleonardokipper
Hi Frans, check this similar question:
Unit Testing problem with Product2 records: A Product with this SKU already exists (https://salesforce.stackexchange.com/questions/290542/unit-testing-problem-with-product2-records-a-product-with-this-sku-already-exis)
Frans Flippo 14Frans Flippo 14

Thanks, Leonardo. That looks like the exact same issue. 


I do think that this points to a definite bug in Salesforce, or at the very least a misrepresentation of how this "test data isolation" works, e.g. on:
- https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_data.htm
- https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_data_access.htm

It's at least odd that Salesforce Customer Support employees like Anudeep don't know about these bugs/limitations. 


I'll raise a support ticket on my company's Salesforce contract and get an official response. At the very least these limitations need to be mentioned in the documentation.