I am using fflib_ApexMocks without any issue till today. However, for this case, I am not able to understand what I am doing wrongly. This is the magical mock:
mocks.when(appointmentServiceMock.isSuitableForAppointment(requestDTO)).thenReturn(true);
Basically using the object 'requestDTO' as parameter the mock is returning null instead of the Boolean. Interestingly, replacing this parameter for another one, for example an string, everything is fine and the boolean is returned...
Following the components:
Apex Resource
@RestResource(urlMapping='/appointment/form/validation')
global with sharing class AppointmentFormValidationRestResource {
@HttpPost
global static void validate() {
AppointmentDTO requestDTO = (AppointmentDTO) JSON.deserialize(
RestContext.request.requestBody.toString(),
AppointmentDTO.class
);
FormValidationResponse formValidationResponseDTO = new FormValidationResponse();
System.debug('m:'+requestDTO);
formValidationResponseDTO.isSuitableForAppointment = AppointmentService.isSuitableForAppointment(requestDTO);
RestContext.response.addHeader('Content-Type', 'application/json');
RestContext.response.statusCode = 200;
RestContext.response.responseBody = Blob.valueOf(JSON.serialize(formValidationResponseDTO));
}
}
Unit Test
@IsTest static void validateTest() {
// Given
AppointmentDTO requestDTO = new AppointmentDTO();
requestDTO.destinations = new List<String>{
'Ibiza'
};
requestDTO.travelDetails.travelWhen = Date.today().addDays(100);
requestDTO.travelDetails.travelPeople = 2;
requestDTO.travelDetails.travelBudget = 1500;
RestRequest request = new RestRequest();
RestResponse response = new RestResponse();
request.requestURI = URL.getSalesforceBaseUrl().toExternalForm() + '/services/apexrest/appointment/form/validation';
request.httpMethod = 'POST';
request.requestBody = Blob.valueOf(JSON.serialize(requestDTO));
RestContext.request = request;
RestContext.response = response;
fflib_ApexMocks mocks = new fflib_ApexMocks();
AppointmentServiceImpl appointmentServiceMock = (AppointmentServiceImpl) mocks.mock(AppointmentServiceImpl.class);
mocks.startStubbing();
System.debug('t:'+requestDTO);
mocks.when(appointmentServiceMock.isSuitableForAppointment(requestDTO)).thenReturn(true);
mocks.stopStubbing();
Application.Service.setMock(IAppointmentService.class, appointmentServiceMock);
// When
Test.startTest();
AppointmentFormValidationRestResource.validate();
Test.stopTest();
// Then
System.assertEquals(200, response.statusCode, 'Error response status code');
String responseBody = response.responseBody.toString();
AppointmentFormValidationRestResource.FormValidationResponse r =
(AppointmentFormValidationRestResource.FormValidationResponse) JSON.deserialize(
responseBody,
AppointmentFormValidationRestResource.FormValidationResponse.class);
System.assertEquals(true,r.isSuitableForAppointment);
}
Service
public with sharing class AppointmentServiceImpl implements IAppointmentService{
[....]
public Boolean isSuitableForAppointment(AppointmentDTO appointmentDTO){
[...]
}
[....]
}
Finally the debug log, in case it can help to identify what is happening
20:39:28.2 (55457059)|USER_DEBUG|[30]|DEBUG|t:AppointmentDTO:[availableAgentIds=null, avoidCreateAppointment=false, calendarProviderEventId=null, consumer=Consumer:[consumerEmail=null, consumerLastName=null, consumerName=null, consumerPhone=null, consumerPostalCode=null], destinations=(Ibiza), endDate=null, eventId=null, office=null, onlineMeetingURL=null, recordId=null, selectedAgentId=null, startDate=null, travelDetails=TravelDetails:[travelBudget=1500, travelPeople=2, travelTellus=, travelWhen=2022-05-22 00:00:00]]
20:39:28.2 (55594654)|SYSTEM_MODE_ENTER|false
20:39:28.2 (69600119)|SYSTEM_MODE_EXIT|false
20:39:28.2 (69654529)|SYSTEM_MODE_ENTER|false
20:39:28.2 (69675333)|SYSTEM_MODE_EXIT|false
20:39:28.2 (69710481)|SYSTEM_MODE_ENTER|false
20:39:28.2 (69814101)|SYSTEM_MODE_EXIT|false
20:39:28.2 (69846058)|SYSTEM_MODE_ENTER|false
20:39:28.2 (69869949)|SYSTEM_MODE_EXIT|false
20:39:28.2 (118052970)|SYSTEM_MODE_ENTER|false
20:39:28.2 (118086146)|SYSTEM_MODE_EXIT|false
20:39:28.2 (118186176)|SYSTEM_MODE_ENTER|false
20:39:28.2 (122565005)|USER_DEBUG|[13]|DEBUG|m:AppointmentDTO:[availableAgentIds=null, avoidCreateAppointment=false, calendarProviderEventId=null, consumer=Consumer:[consumerEmail=null, consumerLastName=null, consumerName=null, consumerPhone=null, consumerPostalCode=null], destinations=(Ibiza), endDate=null, eventId=null, office=null, onlineMeetingURL=null, recordId=null, selectedAgentId=null, startDate=null, travelDetails=TravelDetails:[travelBudget=1500, travelPeople=2, travelTellus=, travelWhen=2022-05-22 00:00:00]]
20:39:28.2 (126263753)|SYSTEM_MODE_EXIT|false
20:39:28.2 (129415400)|EXCEPTION_THROWN|[49]|System.AssertException: Assertion Failed: Expected: true, Actual: null
20:39:28.2 (129750666)|FATAL_ERROR|System.AssertException: Assertion Failed: Expected: true, Actual: null
Class.AppointmentFormValidationRestTest.validateTest: line 49, column 1
20:39:28.2 (129766555)|FATAL_ERROR|System.AssertException: Assertion Failed: Expected: true, Actual: null
Class.AppointmentFormValidationRestTest.validateTest: line 49, column 1
Any idea??