1

I am getting a "you have uncommitted work pending" error on a test. Normally this is caused by a DML statement before a callout. That shouldn't be the case here. However, the code runs fine and I am using Test.start and stop appropriately. Im hoping someone can see what I'm missing.

Here's the class:

//Scheduler public void execute(SchedulableContext sc) { DoseSpotRetrieval dsr = new DoseSpotRetrieval(); Database.executebatch(dsr, 30); } //Loop over accounts (in batches of 30 so calls dont exceed 100) public Database.QueryLocator start(Database.BatchableContext BC){ String query = 'SELECT DoseSpot_Id__c FROM Account WHERE DoseSpot_Id__c != null'; return Database.getQueryLocator(query); } //Handle actual logic public void execute(Database.BatchableContext BC, List<Account> accounts){ String doseSpotSystemUser = Label.DoseSpot_System_User; String authToken = DoseSpotCallout.GetAuthToken(doseSpotSystemUser); getMetadata(); //This is just SOQL List<HealthCloudGA__EhrAllergyIntolerance__c> hcAllergies = new List<HealthCloudGA__EhrAllergyIntolerance__c>(); List<HealthCloudGA__EhrMedicationPrescription__c> hcMedications = new List<HealthCloudGA__EhrMedicationPrescription__c>(); //Check setup data if(String.isBlank(authToken)) { System.debug('Failed to get auth token'); ErrorUtility.CreateSystemLog('DoseSpotRetrieval','GetAuthToken',null,'Failed to get auth token', true); } for(Account a : accounts) { String patientId = a.DoseSpot_Id__c; //Get allergies (Documentation section: 3.1.2), convert to records to hcRecords String urlEndAllergies = '/api/patients/' + patientId + '/allergies'; List<Map<String,Object>> allergies = getDoseSpotData(authToken, urlEndAllergies); //CALLOUT HAPPENS IN THIS METHOD. ITS JUST A CALLOUT, NO DML ... ... ... 

Here's the test class

@TestSetup static void makeData(){ SObjectType sobjType = Schema.getGlobalDescribe().get('Account'); Map<String, Schema.RecordTypeInfo> acctRTs = sobjType.getDescribe().getRecordTypeInfosByDeveloperName(); //Insert patient record Account patient = new Account( Account_Key__c = '123456-09876', FirstName = 'FirstName', LastName = 'LastName', RecordTypeId = acctRTs.get('Sexual_Health_Patient').getRecordTypeId(), DoseSpot_Id__c = '12345' ); insert patient; } @isTest static void testHappyPath() { Test.setMock(HttpCalloutMock.class, new MockResponse(0)); Test.startTest(); DoseSpotRetrieval dsr = new DoseSpotRetrieval(); dsr.execute(null); Test.stopTest(); List<HealthCloudGA__EhrAllergyIntolerance__c> allergies = [SELECT HealthCloudGA__Account__c, DoseSpot_Id__c FROM HealthCloudGA__EhrAllergyIntolerance__c]; List<HealthCloudGA__EhrMedicationPrescription__c> meds = [SELECT HealthCloudGA__Account__c, DoseSpot_Id__c FROM HealthCloudGA__EhrMedicationPrescription__c]; System.assertEquals(1, allergies.size()); System.assertEquals('1', allergies[0].DoseSpot_Id__c); System.assert(allergies[0].HealthCloudGA__Account__c != null, 'Account was not populated on allergy'); System.assertEquals(2, meds.size()); for(HealthCloudGA__EhrMedicationPrescription__c med : meds) { System.assertEquals('1', med.DoseSpot_Id__c); System.assert(med.HealthCloudGA__Account__c != null, 'Account was not populated on med'); } } 

2 Answers 2

0

The documentation states:

The Test.startTest statement must appear before the Test.setMock statement. Also, the calls to DML operations must not be part of the Test.startTest/Test.stopTest block.

You need to change the order of your calls such that Test.startTest occurs before Test.setMock.

5
  • Ive written dozens of tests this way and it works fine Commented Apr 18, 2020 at 1:56
  • @Apexing It sometimes works, yes, but not guaranteed. If you do not follow the directions, you risk having this very issue. Commented Apr 18, 2020 at 1:57
  • Thanks @sfdcfox, I appreciate the info. It looks like it was caused by someone adding DML where I didn't expect it. It seems to be working at the top of the method, but I'll definitely keep an eye out for that going forward. Commented Apr 18, 2020 at 2:00
  • @Apexing Yeah, it's good to follow directions. I myself had that issue once, learned the hard way. I'm glad you were able to find the source of the problem, though. Commented Apr 18, 2020 at 2:01
  • Eh, whatever works... Commented Apr 21, 2020 at 20:27
0

DML got added in the ErrorUtility method that was getting called. Should have checked if that had been added before posting. Thanks for viewing all

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.