I am attempting to test a @future callout class that pings another class to make an API call and update some fields in the Lead object. I am using the mock http method and here's the script:
@isTest
private class MMarkAPITest
{
@isTest
static void MMarkAPIUnitTest() {
//create a lead with website address of testapp.com
Lead l = new Lead
(company = 'Test Company',
status = 'Open',
website = 'testapp.com',
firstname = 'Guy',
lastname = 'Test');
insert l;
Test.startTest();
//set-up a mock callout
Test.setMock(HttpCalloutMock.class, new MMarkAPITestHttpCalloutMock());
// Call method to test.
// This causes a fake response to be sent
// from the class that implements HttpCalloutMock.
MMarkAPI.MMarkAPIFutureCallUpdater('testapp.com');
Test.stopTest();
//access the lead entity
Lead updatedLead = [select Name, Country, Description from Lead where Id = :l.Id];
System.debug('lead is ' +updatedLead);
System.assertEquals(l.description, 'description');
System.assertEquals(l.MZ_Lo__c, 'country');
System.assertEquals(l.YY_Totag__c, 'total funding');
}
}
However when running it with System.assertEquals it fails (all assertions return null value).
On the other hand, when I remove the System.assertEquals the test succeeds but also returns the following message:
System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out
I came across some information regarding DML queries and testing callouts (e g here), but I am struggling to apply it to this problem.
Adding the FutureCallUpdater:
/** CALL FOR THE INSERT UPDATE TRIGGER **/
@future(callout=true)
public static void MMAPIFutureCallUpdater(string domain){
MMAPIUpdater(domain);
}
This triggers that:
public static void MMAPIUpdater(string domain){
list<Lead> leads = [SELECT MM_Description__c FROM Lead WHERE Website LIKE :domain limit 1];
HttpResponse res = MMAPIcallout(domain);
if(res.getStatusCode() == 200 && string.isNotBlank(res.getBody())){
string body = res.getBody();
//system.debug('body before replaced is'+body);
body = body.replace('"currency":', '"deal_currency":');
//system.debug('body after replaced is'+body);
JSON2Apex companyProfile = MMAPIParse(body);
system.debug('company profile is' +companyProfile);
//single ocurring variables
string description = companyProfile.data.description;
//system.debug('description is'+description);
string country = companyProfile.data.country;
//system.debug('location is'+country);
string employees_current = companyProfile.data.employees;
//system.debug('employees_current is'+employees_current);
string employees_month_ago = companyProfile.data.employees_month_ago;
//system.debug('employees_month_ago is'+employees_month_ago);
string employees_6_months_ago = companyProfile.data.employees_6_months_ago;
//system.debug('employees_6_months_ago'+employees_6_months_ago);
string total_funding = companyProfile.data.total_funding;
//system.debug('total_funding is'+total_funding);
string last_funding_amount = companyProfile.data.last_funding_amount;
//system.debug('last_funding_amount is'+last_funding_amount);
string last_funding_date = companyProfile.data.last_funding_date;
//system.debug('last_funding_date is'+last_funding_date);
//convert list variables into strings
//business_models
List <String> businessModels = companyProfile.data.business_models;
string commaSeparatedBusinessModels = '';
if(businessModels != null){
//system.debug('the business models list it' +business_models);
for (String model:businessModels ){
commaSeparatedBusinessModels += model + ', ';
}
//system.debug('comma separted business models are'+commaSeparatedBusinessModels);
}
//acquired_by
List <Meta> acquiredBy = companyProfile.data.acquired_by;
string commaSeparatedAcquiredBy = '';
if(acquiredBy != null){
for (Meta acquirer:acquiredBy){
commaSeparatedAcquiredBy += acquirer + ', ';
}
}
// singular variables to be inserted into Lead objects
for(Lead l:leads){
l.MM_Business_Models__c = commaSeparatedBusinessModels;
l.MM_Description__c = description;
l.MM_Location__c = country;
l.MM_employees_current__c = employees_current;
l.MM_employees_1M_Ago__c = employees_month_ago;
l.MM_employees_6M_Ago__c = employees_6_months_ago;
l.MM_Total_Funding__c = total_funding;
l.MM_Last_Funding_Amount__c = last_funding_amount;
l.MM_Last_Funding_Date__c = last_funding_date;
l.MM_Acquirers__c = commaSeparatedAcquiredBy;
}
try {
update leads;
} catch (DmlException e) {
System.debug(e.getMessage());
}
//lists of variables to be inserted into custom objects
/*
MM_Funding_History__c
To ensure deals are added only once (no duplicates), the script invokes the lead with the relevant ID number
(obtained by looking for a lead with the relevant domain) and creates a string of funding deal dates (dealDatesInString)
separated by a comma. Subsequently, upon lead update only funding rounds with the date
not appearing on the list are added to the Lead (if (!dealDatesInString.contains(deal.funding_date))
*/
string LeadId = getLeadID(domain);
List <Funding> funding = companyProfile.data.funding;
List<MM_Funding_History__c> dealsList = [SELECT MM_Date__c FROM MM_Funding_History__c WHERE MM_Funding_History_To_Lead__c = :LeadId];
//system.debug('the list is' +dealsList);
//ensuring that the deals are added only once
string dealDatesInString = '';
for (MM_Funding_History__c d :dealsList){
dealDatesInString += d + ', ';
}
//system.debug('deal dates string is' +dealDatesInString);
for(Funding deal:funding){
//ensuring deals are added only if they're not already on the list (using MM_Date__c as unique identifier)
if (!dealDatesInString.contains(deal.funding_date)){
MM_Funding_History__c row = new MM_Funding_History__c(
MM_Funding_History_To_Lead__c = getLeadID(domain),
MM_Amount__c = deal.amount,
MM_Date__c = deal.funding_date,
MM_Funding_Type__c = deal.series,
MM_Investors__c = deal.investors,
MM_Currency__c = deal.deal_currency);
//system.debug('this is row' +row);
insert row;
}
}
}
}
MMarkAPIFutureCallUpdater
– EricSSH Jun 13 '17 at 16:58