Home > Net >  Mock object method call returns false
Mock object method call returns false

Time:01-03

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");
  • Related