So I'm familiar with the error
System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out
but I'm stumped with this one! I have a call with a @future method that makes a callout then implements some DML, which is called by a trigger whenever Cases are inserted. Thing is, when testing in sandbox everything works fine - it's only during a deployment that the error is returned.
My class w/ @future method:
public with sharing class Case_Handler {
@future (callout=true)
static public void CurrencyConversion(set<ID> caseIDList) {
Http http = new http();
HttpRequest req = new HttpRequest();
HttpResponse res = new HttpResponse();
req.setEndpoint('https://openexchangerates.org/api/latest.json?app_id=27f541f3a34b4cafa91105ac17d9ca8f');
req.setTimeout(60000);
req.setMethod('GET');
res = http.send(req);
system.debug(res.getbody());
list<Case> caseList = [SELECT CreatedDate, Revenue__c, Currency__c, Revenue_Original_Currency__c FROM Case WHERE ID IN :caseIDList];
list<Currency_Exchange_Rates__c> cerList = new list<Currency_Exchange_Rates__c>();
for(Case c : caseList){ **DML Statements happen in here**
etc...
My trigger
trigger Case_CurrencyConversion on Case (after insert) {
Case_Handler.CurrencyConversion(trigger.newMap.keySet());
}
My test class
@isTest
private class Case_CurrencyConversion_Test implements HttpCalloutMock{
public HTTPResponse respond(HTTPRequest req) {
//System.assertEquals('http://api.salesforce.com/foo/bar', req.getEndpoint());
//System.assertEquals('GET', req.getMethod());
// Create a fake response
HttpResponse res = new HttpResponse();
res.setHeader('Content-Type', 'application/json');
res.setBody('{"disclaimer":"Exchange rates are provided for informational purposes only, and do not constitute financial advice of any kind. Although every attempt is made to ensure quality, NO guarantees are given whatsoever of accuracy, validity, availability, or fitness for any purpose - please use at your own risk. All usage is subject to your acceptance of the Terms and Conditions of Service, available at: https://openexchangerates.org/terms/","license":"Data sourced from various providers with public-facing APIs; copyright may apply; resale is prohibited; no warranties given of any kind. Bitcoin data provided by http://coindesk.com. All usage is subject to your acceptance of the License Agreement available at: https://openexchangerates.org/license/","timestamp":1427400062,"base":"USD","rates":{"AED":3.67287,"AFN":57.743533,"ALL":128.1274,"AMD":473.356002,"ANG":1.78952,"AOA":107.534251,"ARS":8.801325,"AUD":1.279481,"AWG":1.795,"AZN":1.048575,"BAM":1.795899,"BBD":2,"BDT":77.85953,"BGN":1.795321,"BHD":0.377012,"BIF":1560.42,"BMD":1,"BND":1.368998,"BOB":6.90733,"BRL":3.179781,"BSD":1,"BTC":0.0039544401,"BTN":62.587816,"BWP":9.81483,"BYR":14553.233333,"BZD":1.997243,"CAD":1.248137,"CDF":927.1845,"CHF":0.962274,"CLF":0.024602,"CLP":622.242199,"CNY":6.192248,"COP":2559.085039,"CRC":533.170305,"CUC":1,"CUP":0.99985,"CVE":100.754374,"CZK":25.21538,"DJF":177.6412,"DKK":6.855725,"DOP":44.69114,"DZD":96.622469,"EEK":14.337525,"EGP":7.627253,"ERN":15.114767,"ETB":20.40937,"EUR":0.919121,"FJD":2.035896,"FKP":0.673526,"GBP":0.673526,"GEL":2.222588,"GGP":0.673526,"GHS":3.792465,"GIP":0.673526,"GMD":43.01859,"GNF":7296.384922,"GTQ":7.63688,"GYD":206.109002,"HKD":7.755124,"HNL":21.49481,"HRK":7.021803,"HTG":47.3988,"HUF":275.243098,"IDR":12993.883333,"ILS":3.954727,"IMP":0.673526,"INR":62.7263,"IQD":1184.276667,"IRR":27892.666667,"ISK":135.853,"JEP":0.673526,"JMD":114.824601,"JOD":0.708552,"JPY":119.317001,"KES":92.058811,"KGS":63.037501,"KHR":4018.81665,"KMF":451.362695,"KPW":899.91,"KRW":1105.141675,"KWD":0.299766,"KYD":0.820343,"KZT":185.8425,"LAK":8113.140065,"LBP":1507.126667,"LKR":132.9905,"LRD":84.553335,"LSL":11.94438,"LTL":2.933767,"LVL":0.644846,"LYD":1.369931,"MAD":9.854486,"MDL":18.52518,"MGA":3007.028366,"MKD":56.5572,"MMK":1046.1125,"MNT":1985.833333,"MOP":7.969258,"MRO":315,"MTL":0.394649,"MUR":36.37293,"MVR":15.258838,"MWK":443.832299,"MXN":15.09305,"MYR":3.671121,"MZN":35.7355,"NAD":11.94438,"NGN":199.099701,"NIO":26.78082,"NOK":7.894581,"NPR":99.98331,"NZD":1.320448,"OMR":0.385011,"PAB":1,"PEN":3.078775,"PGK":2.661019,"PHP":44.82448,"PKR":101.973999,"PLN":3.750491,"PYG":4810.941589,"QAR":3.641241,"RON":4.061622,"RSD":110.780999,"RUB":57.39713,"RWF":690.4415,"SAR":3.750843,"SBD":7.716739,"SCR":13.71065,"SDG":5.958921,"SEK":8.564549,"SGD":1.370576,"SHP":0.673526,"SLL":4345,"SOS":700.086302,"SRD":3.2825,"STD":22432.083333,"SVC":8.72256,"SYP":211.78,"SZL":11.94438,"THB":32.54761,"TJS":5.7148,"TMT":3.499933,"TND":1.943006,"TOP":2.025876,"TRY":2.59737,"TTD":6.348941,"TWD":31.25631,"TZS":1841.041667,"UAH":21.758274,"UGX":2968.59,"USD":1,"UYU":25.48513,"UZS":2487.383301,"VEF":6.31842,"VND":21511.666667,"VUV":105.348334,"WST":2.472739,"XAF":601.660469,"XAG":0.0585635,"XAU":0.00083129,"XCD":2.70102,"XDR":0.719741,"XOF":601.109009,"XPF":109.74309,"YER":215.0641,"ZAR":11.94981,"ZMK":5253.075255,"ZMW":7.586915,"ZWL":322.355006}}');
res.setStatusCode(200);
return res;
}
static testmethod void test_method_one() {
// Implement test code
Test.setMock(HttpCalloutMock.class, new Case_CurrencyConversion_Test());
list<Case> cases = new list<Case>{new Case(Revenue_Original_Currency__c = 100,
Currency__c = 'GBP'),
new Case(Revenue_Original_Currency__c = 100,
Currency__c = 'USD'),
new Case(Revenue_Original_Currency__c = 200,
Currency__c = 'GBP'),
new Case(Revenue_Original_Currency__c = 100)};
Test.startTest();
insert cases;
Test.stopTest();
...
test assertions, etc...
EDIT: In response to the suggestion that I separate the testing of the trigger and the @future call, here is the new code I tried but received the same issue:
static testmethod void test_method_one() {
// Implement test code
Test.setMock(HttpCalloutMock.class, new Case_CurrencyConversion_Test());
list<Case> cases = new list<Case>{new Case(Revenue_Original_Currency__c = 100,
Currency__c = 'GBP'),
new Case(Revenue_Original_Currency__c = 100,
Currency__c = 'USD'),
new Case(Revenue_Original_Currency__c = 200,
Currency__c = 'GBP'),
new Case(Revenue_Original_Currency__c = 100)};
insert cases;
set<ID> caseIDs = new set<ID>();
for(Case c : cases) caseIDs.add(c.ID);
Test.startTest();
Case_Handler.CurrencyConversion(caseIDs);
Test.stopTest();