Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Mock object method call returns false

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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("sample@gmail.com", "Sales"))
            .thenReturn(true);

    boolean sent = batchJob.generateWeeklyReport("Sales", "sample@gmail.com");

    System.out.println(sent);
}

The printed output is false.

Am I missing something here?
Hope you can help me with this. Thank you!

>Solution :

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("sample@gmail.com", "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("sample@gmail.com", "The Sales weekly report generated");
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading