I spent the entire day re-writing all my tests because of issues I was running into in this question from yesterday. For the most part I am done, but am running into a:
System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out
...exception which I can't resolve. The exception occurs in this chunk of code:
@RemoteAction
public static void ImageSave(
ImageSaveFormModel form) {
vNOpportunityPhoto__c photo = [
SELECT ResizedFile__r.Extension__c,
ResizedFile__r.FileSize__c,
ResizedFile__r.S3Key__c,
ThumbnailFile__r.Extension__c,
ThumbnailFile__r.FileSize__c,
ThumbnailFile__r.S3Key__c
FROM vNOpportunityPhoto__c
WHERE (Id = :form.OpportunityPhotoId)
];
// The exception occurs here
vNKrakenService.KrakenResponse resizedOptimizeWaitResponse = vNKrakenClient.OptimizeWait(form.ResizedBlob, photo.ResizedFile__r.S3Key__c);
if (!resizedOptimizeWaitResponse.Success) {
System.debug('Resized optimization failed, error: ' + resizedOptimizeWaitResponse.Error);
return;
}
blob resizedBlob = vNKrakenClient.DownloadFile(resizedOptimizeWaitResponse);
vNKrakenService.KrakenResponse thumbnailOptimizeWaitResponse = vNKrakenClient.OptimizeWait(resizedBlob, photo.ThumbnailFile__r.S3Key__c, 140, 140);
if (!thumbnailOptimizeWaitResponse.Success) {
System.debug('Thumbnail optimization failed, error: ' + thumbnailOptimizeWaitResponse.Error);
return;
}
blob thumbnailBlob = vNKrakenClient.DownloadFile(thumbnailOptimizeWaitResponse);
boolean resizesPutResult = vNAwsS3Client.PutObject(photo.ResizedFile__r.S3Key__c, resizedBlob);
if (!resizesPutResult) {
System.debug('Resize put failed, bailing out.');
return;
}
boolean thumbnailPutResult = vNAwsS3Client.PutObject(photo.ThumbnailFile__r.S3Key__c, thumbnailBlob);
if (!thumbnailPutResult) {
System.debug('Thumbnail put failed, bailing out.');
return;
}
if (!Test.isRunningTest()) {
photo.ResizedFile__r.FileSize__c = resizedBlob.size();
photo.ThumbnailFile__r.FileSize__c = thumbnailBlob.size();
update photo.ResizedFile__r;
update photo.ThumbnailFile__r;
}
}
...however, there are no DML operations occurring anywhere in the call stack, UNLESS the test engine is deciding that the SOQL queries are a DML operation? The test is like this, and the test class mocks up fake objects using an @TestSetup
method:
@IsTest
public static void ImageSave() {
System.debug('OpportunityPhotosControllerTests.ImageSave');
vNOpportunityPhoto__c opportunityPhoto = [
SELECT Id
FROM vNOpportunityPhoto__c
LIMIT 1
];
vNOpportunityPhotosController.ImageSaveFormModel imageSaveForm = new vNOpportunityPhotosController.ImageSaveFormModel();
imageSaveForm.OpportunityPhotoId = opportunityPhoto.Id;
imageSaveForm.Resized64 = '/9j';
Test.setMock(HttpCalloutMock.class, new vNTestsHttpMocks());
Test.startTest();
vNOpportunityPhotosController.ImageSave(imageSaveForm);
Test.stopTest();
}
What can I do to resolve this? I've been trying to get unit tests to work for three days now only to be blocked by the callout exception which is a lie... There are no triggers in the app, and the workflows that exist will not be triggered, and even if they were they only send out emails.
Update 1
Per @Santanu Boral's suggestion I moved the Test.setMock()
to be after Test.startTest()
, not before it. It didn't help, and I really don't think the order of the Test class methods matters. Here's a screenshot of the log file after the change which is identical to before the change.
Update 2
So, I went through and disabled all workflow rules on Opportunity. When I did that the exception disappeared, there were no errors in the log, yet the classes refused to save to the server. No exception, no error, and no save, thanks Salesforce for working so well...
Anyway, I then reactivated each workflow rule one by one until the exception reappeared again on the very last rule. This rule just sends out an email and performs no DML operations.
At this point I have no idea what to do or say and I'm just very angry and frustrated. All I know is that the day my company leaves Salesforce will be a glorious day of happiness. Until then I'm stuck pretty much incapable of doing anything.