I am confused on how this works. I am trying to use mocks on my tests but it seems glitchy or something ( idk ). Here is the sample code.
I have EmailSender class with username, password and emailServer attributes with all args constructor ( not using lombok though just the term ). Inside the class is this method below:
public boolean sendEmail(String toAddress, String emailText) {
return true;
}
This EmailSender will be consumed by WeeklyReportsBatchJob.
private final EmailSender emailSender;
public WeeklyReportsBatchJob(EmailSender emailSender) {
this.emailSender = emailSender;
}
public boolean generateWeeklyReport(String reportType, String emailRecipient) {
return emailSender.sendEmail(emailRecipient,
String.format("The %s weekly report generated", reportType));
}
This should return true as I hardcoded the return value of emailSender.sendEmail method. But after adding the test, the return value is false. See below test:
public class WeeklyReportsBatchJobTest {
@Mock
private EmailSender emailSenderMock;
private AutoCloseable closeable;
@BeforeEach
public void setupMocks() {
closeable = openMocks(this);
}
@AfterEach
public void releaseMocks() throws Exception {
closeable.close();
}
}
and the @Test itself:
@Test
public void testGenerateWeeklyReport_singleRecipient() {
WeeklyReportsBatchJob batchJob = new WeeklyReportsBatchJob(emailSenderMock);
when(emailSenderMock
.sendEmail("[email protected]", "Sales"))
.thenReturn(true);
boolean sent = batchJob.generateWeeklyReport("Sales", "[email protected]");
System.out.println(sent);
}
The printed output is false.
Am I missing something here? Hope you can help me with this. Thank you!
CodePudding user response:
When we take a look at the production code, in particular this method:
public boolean generateWeeklyReport(String reportType, String emailRecipient) {
return emailSender.sendEmail(emailRecipient, String.format("The %s weekly report generated", reportType));
}
We see that the 2nd parameter passed along to the emailSenderMock
is not "Sales"
, but "The Sales weekly report generated"
. Hence, we need to rewrite the mock accordingly:
when(emailSenderMock
.sendEmail("[email protected]", "The Sales weekly report generated"))
.thenReturn(true);
i would suggest to separate mocking from validation, i.e. we can direct the mock to always return true
:
when(emailSenderMock.sendEmail(anyString(), anyString())
.thenReturn(true)
and validate the actual parameters later:
verify(emailSenderMock)
.sendEmail("[email protected]", "The Sales weekly report generated");