+ Start a Discussion

Custom Settings and Unit Testing with API v24

We're trying to embrace best practices by externalizing some of our constants and configurations.  We've adopted Custom Settings in that vein.  Similiarly, we're looking to transition our unit tests to the newest api version (v24) since, by default, it isolates test data from existing data in Salesforce.  This is desirable since it will ensure our tests remain portable between different orgs -especially development sandboxes that don't have any data by default.


This is where we've hit a problem.  Using v24, none of our custom settings are available when the test starts.  Fine. Just like Accounts or Contacts, we'll create the data required by our tests.  So, I create the custom setting (in the example below, that's My_Custom_Setting__c).


Now the custom setting is available.  Then, when I test my actual code later in the test method, I make calls to My_Custom_Setting__c.getInstance(...), to get the custom setting.  Unfortunately, it returns null.  This is unfortunate since using getInstance(...) is the recommended way to access custom settings in code.  Why?  Because it's cached in the application cache and therefore very fast and efficient.


I'm going to guess that the below test fails because... when the application cache loads at the beginning of the test, there are no custom settings to cache.  Later on, when I insert the custom setting, the cache is not updated.  For this reason, furture calls to getInstance() don't return the custom setting I just inserted.  I would love it if someone could verify this.  I'm just guessing.


If that is the case, what's a developer to do? 


  1. Is there some way to refresh the application cache when custom settings are inserted?  I had hoped that inserting a custom setting the cache would be updated.
  2. Do I need to switch all of my code away from calling My_Custom_Setting__C.getInstance(...), to something like [Select ... from My_Custom_Setting_c Where Name = 'Standard Setting']?  If you run the below test, you'll see that querying for the custom setting using SOQL DOES return my just-inserted custom setting.  There's no caching there.
  3. Should I introduce a utility method that will need to be called whenever a piece of code requires my custom settings?  The method could check if it's running in a test context (Test.isRunningTest).  If so, it would do the SELECT, if not, it would call getInstance().

Thoughts?  Either I'm missing something, or this really is just a current difficiency in how Custom Settings are implemented.  I really want to migrate my tests to v24, but I would prefer not having to refactor non-test code to do it.




//Test with api v24    
@isTest static void testAumConfig()
        My_Custom_Setting__c c = new My_Custom_Setting__c();
        c.Name = 'Standard Configuration';
        insert c;
        List<My_Custom_Setting__c> cs = [Select Id from My_Custom_Setting__c Where Name = 'Standard Configuration']; 
        System.assert(cs.size() == 1);
        c = My_Custom_Setting__c.getInstance('Standard Configuration');
        System.assert(c != null); //this fails.  It doesn't find the custom setting, even though I just inserted it above!!!



Hi Andrew,

I ran into same issue.


Ironically, a few days after my initial post, this just started working as expected.  I don't know if there was an issue in sandbox that was fixed, but our test passed.  The code seemed to recognize the custom settings created in our unit tests.  Sorry, I know that's not helpful.  We're operating on CS12.





Currently we are working on developer sandbox on cs3.

We'll try other instances and post our findings


Thanks for your prompt response



Andy BoettcherAndy Boettcher

Howdy!  I ran into this and actually found out what ended up working for me:


I had exactly the code structure you had - but I had to literally create the Custom Setting record in my Unit Test itself - then it worked.


static testMethod void testThisThing() {

     CustomSetting__c cs = new CustomSetting__c();
     cs.Name = 'Test Custom Setting';
     insert cs;

     <other methods to test>




Roger WickiRoger Wicki
Hi folks

I've had the same problem as well during testing. The key is that Custom Settings sort of work protected/hidden. If you use @isTest(SeeAllData=true) it should work. At least after changing that the following code didn't throw errors anymore:

private CustomSetting__c cs;
[ ... ]
cs = CustomSetting__c.getOrgDefaults();
[ ... ]
aMap.put('aString', new list<String>(cs.CustomField__c.split(',')));         // It is a text field with comma as delimiter for string values
<Other Code>