I am writing a test class for testing webservice callouts as a part of one of the challenges of Data Integration Specialist superbadge. Here I am creating test data by inserting some custom object records in a test data utility class. Following is my code:
Test class:
@isTest
private class BillingCalloutServiceTest {
@isTest(seeAllData = true)
static void positiveTest(){
Test.setMock(WebServiceMock.class, new BillingCalloutServiceMock());
List<Project__c> testProjectList = TestDataFactory.createTestProjectData();
Set<Id> idSet = new Set<Id>();
for(Project__c proj : testProjectList){
idSet.add(proj.Id);
proj.status__c = 'Billable';
}
test.startTest();
update testProjectList;
test.stopTest();
for(Project__c proj : [select status__c from Project__c where id in: idSet]){
system.assertEquals('Billed', proj.Status__c);
}
}
}
Test Data Utility class:
@isTest
public class TestDataFactory {
//Own code
public static List<Project__c> createTestProjectData(){
List<Project__c> testProjectList = new List<Project__c>();
Project__c project1 = new Project__c(Name = 'Test Project 2', Opportunity__c = '0067F000007HlExQAK');
Project__c project2 = new Project__c(Name = 'Test Project 3', Opportunity__c = '0067F000007HlF5QAK');
Project__c project3 = new Project__c(Name = 'Test Project 4', Opportunity__c = '0067F000007HlFDQA0');
testProjectList.add(project1);
testProjectList.add(project2);
testProjectList.add(project3);
insert testProjectList;
return testProjectList;
}
}
This works correctly. But if I remove (seeAlldata = true) from @isTest
annotation, I get null pointer exception in my apex class that is to be tested as it does not get any data :
Apex trigger that further calls webservice callout code that is to be tested:
trigger ProjectTrigger on Project__c (after update) {
//Call the Billing Service callout logic here
////Own code
Map<String, Double> refToBillAmountMap = new Map<String, Double>();
String oldStatus;
String newStatus;
ServiceCredentials__c cred = ServiceCredentials__c.getValues('BillingServiceCredential');
for(Project__c project : trigger.new){
oldStatus = trigger.oldMap.get(project.Id).Status__c;
newStatus = trigger.newMap.get(project.Id).Status__c;
if(oldStatus != newStatus && newStatus == 'Billable'){
refToBillAmountMap.put(project.ProjectRef__c, project.Billable_Amount__c);
}
}
if(!refToBillAmountMap.keySet().isEmpty())
BillingCalloutService.callBillingService(refToBillAmountMap,cred.Username__c,cred.Password__c);
}
As per this trailhead, no where is the seeAllData = true
tag put, and it is working. What is the reason I am getting this exception? Also, it does not make sense to use this tag as we are not using org data, but rather creating it ourselves in test class.
Callout service:
global class BillingCalloutService {
//Implement business and callout logic methods here
//Own code
public static void callBillingService(Map<String, Double> refToBillAmountMap,String uname,String pswd){
billProject(refToBillAmountMap,uname,pswd);
}
@future(callout = true)
private static void billProject(Map<String, Double> refToBillAmountMap,String uname,String pswd){
Set<String> projectRefSet = new Set<String>();
Boolean doUpdate = true;
try{
for(String projectRef : refToBillAmountMap.keySet()){
BillingServiceProxy.project project = new BillingServiceProxy.project();
project.username = uname;
project.password = pswd;
project.projectRef = projectRef;
project.billAmount = refToBillAmountMap.get(projectRef);
BillingServiceProxy.InvoicesPortSoap11 callout = new BillingServiceProxy.InvoicesPortSoap11();
String status = callout.billProject(project);
if(status.equalsIgnoreCase('OK')){
projectRefSet.add(projectRef);
}
else{
doUpdate = false;
}
}
if(doUpdate){
List<Project__c> projectListToBeUpdated = new List<Project__c>();
for(Project__c proj : [select status__c
from Project__c
where ProjectRef__c in: projectRefSet]){
proj.status__c = 'Billed';
projectListToBeUpdated.add(proj);
}
update projectListToBeUpdated;
}
}
catch(DmlException e){
system.debug('Exception DML : ' + e.getMessage());
}
catch(CalloutException e){
system.debug('CalloutException : ' + e.getMessage());
}
}
}