2

It appears that my Dev org's custom settings are not available within the scope of a unit test so I've written code to insert the needed custom setting within the test.

I have a callout method which I need to test that accesses the custom setting. When the method executes it throws an exception informing me that I may not execute DML prior to the callout. Since the callout method needs access to the custom setting prior to making the callout I'm presented with a bit of a problem.

In this case, the callout method is checking the custom setting for a token expiration datetime. If the value of the token's datetime has already elapsed, the callout isn't made, instead the token value is taken from the custom setting. But if the datetime's value has already elapsed the callout is made for a fresh token/token expiration datetime and the custom setting is updated.

So how can this callout method be properly tested given the above DML limitation? I'm also using a MultiStaticResourceCalloutMock for the callout response, but the code never gets far enough along to use it before encountering the exception.

Any ideas on how to resolve the issue or perhaps a workaround to avoid it entirely?

1
  • I'm also pulling some values from the same custom setting for authentication with an endpoint that the callout needs.
    – SF1Dev
    Commented Jul 22, 2014 at 16:24

2 Answers 2

3

Often, this problem can be solved by doing the following steps in order in your test class.

  1. Insert custom setting
  2. Call Test.startTest()
  3. Set your mock
  4. Make callout
  5. Call Test.stopTest()

The key is calling Test.startTest() which gets rid of the pending dml error. If that doesn't work, you can try doing the custom setting insert inside of System.runas block.

1
  • I had my Test.startTest() line above my custom setting creation code. Thanks!
    – SF1Dev
    Commented Jul 22, 2014 at 17:03
4

As an alternative to Daniel's great answer, one thing that we do at my org is created a Settings class to handle the fetching of settings. Methods within this class always return an instance of the custom setting. Instead of referencing custom settings directly, we always call the Settings class in all code that uses settings, which then instantiates the custom setting in the transaction in prod only if it hasn't already been fetched. And then in tests, we use the Settings class to set defaults and create the instance of the custom setting only in memory without actually performing a DML. This has helped tremendously in working with settings alongside callouts and the dreaded uncommitted work pending errors.

1
  • It's a good idea that I should have already implemented. I will be making this change as well. Thanks!
    – SF1Dev
    Commented Jul 22, 2014 at 17:05

You must log in to answer this question.

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