You are creating a spy using only a class parameter in the spy()
method, so Mockito does not know about any object that should be injected into the created spy object.
To inject the missing dependency you can pick one of three approaches (one without modification of the actual code). For the sake of simplification in the example I've stripped the objects as complete code was not provided.
Let's assume field injection first (here's more on why it's discouraged to use field injection):
class EncryptionService {
void encrypt() {
System.out.println("Encrypted!");
}
}
class CredentialsService {
EncryptionService encryptionService;
void process() {
encryptionService.encrypt();
}
}
Annotations
@Mock // or @Spy, or actual object
EncryptionService encryptionService;
@Spy
@InjectMocks // this tells Mockito to inject dependencies
CredentialsService credentialsService;
@BeforeEach
void setUp() {
// here the injection actually happens
// openMocks() in more recent versions of Mockito
MockitoAnnotations.initMocks(this);
}
@Test
void annotationInjection() {
credentialsService.process();
}
For both approaches below we will need the dependencies to be injected in a constructor, so CredentialsService
looks like this:
class CredentialsService {
EncryptionService encryptionService;
CredentialsService(EncryptionService encryptionService) {
this.encryptionService = encryptionService;
}
void process() {
encryptionService.encrypt();
}
}
Mock settings
@Test
void mockWithSettings() {
var credentialsService = mock(CredentialsService.class, withSettings()
// EncryptionService could be also a mock or a spy
.useConstructor(new EncryptionService())
// actually acts like a spy thanks to the below setting
.defaultAnswer(CALLS_REAL_METHODS));
credentialsService.process();
}
(read more in the Mockito documentation)
Spy on an object
@Test
void spyOnObject() {
var encryptionService = mock(EncryptionService.class);
var credentialsService = spy(new CredentialsService(encryptionService));
credentialsService.process();
}
I'm usually using the first or last approach from the ones above (but the first one with dependencies injected by constructor - it works as well).