I'm making a unit test on a method that uses two static classes. So, inside the test I have this
try(MockedStatic<SecurityEncryption> securityEncryption = mockStatic(SecurityEncryption.class);
MockedStatic<SecretUtils> secretUtils = mockStatic(SecretUtils.class)
){
secretUtils.when(() -> SecretUtils.getSecret(anyString(), anyString())).thenReturn("secreto");
securityEncryption.when(() -> SecurityEncryption.desencriptarString(anyString(), anyString())).thenReturn("texto");
assertEquals("texto", SecurityEncryption.desencriptarString("", ""));
notificationSendEmailService.sendNotificationEmail("", "", "");
}
The first class, SecretUtils is returning the mocked value, "secreto". But, the second one is always null, no matter what I do, always null inside the class that I'm testing, notificationSendEmail.
I thought the class was not mocked, but the assertion passes, so is inside the method that is not working, also I print the getSecret method inside my sendNotificationEmail and is "secreto", the other one, desencriptarString is always null.
What I'm doing wrong? D:
The service I'm testing has @InjectMocks
annotation, and in @BeforeEach
method is the MockitoAnnotations.openMocks(this)
line.
I don't want to use PowerMockito btw.
CodePudding user response:
Would you mind sharing a bit more code? Because the problem is not reproducible. The following minimal but representative example works in my environment. I hope it helps.
UPD: Most likely your version of NotificationSendEmailService
calls an overloaded version of SecurityEncryption.desencriptarString
that has a different signature, i.e. different arguments instead of two String
arguments. And that version is not mocked in your test. Anyway, a bit more details of NotificationSendEmailService
(and others) will really help.
- NotificationSendEmailService
public class NotificationSendEmailService {
void sendNotificationEmail(String a, String b, String c) {
var secreto = SecretUtils.getSecret(a, b);
System.out.println(secreto);
assert "secreto".equals(secreto); // throws here if not properly mocked
var texto = SecurityEncryption.desencriptarString(b, c);
System.out.println(texto);
assert "texto".equals(texto); // throws here if not properly mocked
}
}
- SecretUtils
public class SecretUtils {
static String getSecret(String a, String b) {
throw new UnsupportedOperationException("Not thrown if properly mocked in test");
}
}
- SecurityEncryption
public class SecurityEncryption {
static String desencriptarString(String b, String c) {
throw new UnsupportedOperationException("Never thrown when properly mocked in test");
}
}
- test/resource/mockito-extensions/org.mockito.plugins.MockMaker
This can also be configured differently.
mock-maker-inline
- NotificationSendEmailServiceTest
PASSES as both classes are properly mocked. Otherwise it would have failed with UnsupportedOperationException
.
public class NotificationSendEmailServiceTest {
@Test
void sendNotificationEmail() {
var notificationSendEmailService = new NotificationSendEmailService();
// the following is copy-pasted from the original question
try (MockedStatic<SecurityEncryption> securityEncryption = mockStatic(SecurityEncryption.class);
MockedStatic<SecretUtils> secretUtils = mockStatic(SecretUtils.class)
) {
secretUtils.when(() -> SecretUtils.getSecret(anyString(), anyString())).thenReturn("secreto");
securityEncryption.when(() -> SecurityEncryption.desencriptarString(anyString(), anyString())).thenReturn("texto");
assertEquals("texto", SecurityEncryption.desencriptarString("", ""));
notificationSendEmailService.sendNotificationEmail("", "", "");
}
}
}