I find myself in a situation where I do not know the test code answers. I have an Impl with a single method that looks for a patient, but inside that method I have another external class that calls a method that also calls an interface to receive the response. I expose my code
IMPL
@Autowired
private JwtServices jwtServices;
@Override
public Map<String, Object> findByPatient(String identificationNumber, String birthdate, Boolean allowPatientData) {
Map<String, String> jwtData = jwtServices.getDecoderJwt();
Map<String, String> dataPatient = new HashMap<>();
dataPatient.put("identificationNumber", identificationNumber);
dataPatient.put("birthdate",birthdate);
dataPatient.put("allowPatientData",allowPatientData.toString());
dataPatient.put("appointmentId",jwtData.get("sub"));
return this.apiFaroConfig.findPatient(dataPatient);
}
My code JwtServices:
@Autowired
private JWTDecoder jwtDecoder;
public Map<String, String> getDecoderJwt(){
Map<String, String> jwtData = new HashMap<>();
Payload payloadHeaderAuthorization = jwtDecoder.getPayloadAuthorization();
jwtData.put("iss", payloadHeaderAuthorization.getIss());
jwtData.put("sub", payloadHeaderAuthorization.getSub());
return jwtData;
}
My test IMPL:
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
class PatientServicesImplTest {
@Mock
private FaroApiRest apiFaroRest;
@InjectMocks
private JwtServices jwtServices ;
@Mock
private JWTDecoder jwtDecoder;
@Mock
private Payload payload;
@InjectMocks
private PatientServicesImpl patientServices;
//Initialize variable
private Map<String, String> dataPatient;
private Map<String, Object> dataResponse;
private Map<String, String> jwtData ;
@BeforeEach
void setUp() {
//Initialize instances
patientServices = new PatientServicesImpl(apiFaroRest);
dataPatient = new HashMap<>();
dataResponse = new HashMap<>();
jwtData = new HashMap<>();
//initialize dataPatient
dataPatient.put("identificationNumber", "XXXX");
dataPatient.put("birthdate","XXXX");
dataPatient.put("allowPatientData", "true");
dataPatient.put("appointmentId","XXX");
//Initialize dataResponse status->200 ok
dataResponse.put("datosPersonales", "XXX");
dataResponse.put("anamnesis", "XXX");
dataResponse.put("gdpr", "XXX");
//Initialize data jwt
jwtData.put("iss","560");
jwtData.put("sub", "123456");
}
@Test
void findByPatient() {
//when
//Jwt Services
when(jwtDecoder.getPayloadAuthorization()).thenReturn(payload);
when(jwtServices.getDecoderJwt()).thenReturn(jwtData);
//PatientsImpl
when(patientServices.findByPatient("XXXX", "XXXX", true)).thenReturn(dataResponse);
when(apiFaroRest.findPatient(dataPatient)).thenReturn(dataResponse);
//given
Map<String, Object> response = apiFaroRest.findPatient(dataPatient);
//then
assertTrue(response.containsKey("datosPersonales"));
assertNotNull(response);
}
}
Error:
org.mockito.exceptions.misusing.WrongTypeOfReturnValue:
HashMap cannot be returned by getSub()
getSub() should return String
***
If you're unsure why you're getting above error read on.
Due to the nature of the syntax above problem might occur because:
1. This exception *might* occur in wrongly written multi-threaded tests.
Please refer to Mockito FAQ on limitations of concurrency testing.
2. A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies -
- with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method.
I don't understand what's going on. I don't understand why I get that return change when I'm specifying its return. Then, if I remove the jwtDecoder it returns null jwtService because it tries to call the jwtDecoder method and it doesn't "exist" but of course, if what I want is that the JwtServices checks its getDecoder method and I return it the Map<String, String> so that the main IMPL method can give me the OK.