Josh Josh - 20 days ago 5
Java Question

How to test Date functions that should return a specific date

I have the following function:

public static Date getFirstOfLastMonth() {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.MONTH, -1);
cal.set(Calendar.DAY_OF_MONTH, 1);

return cal.getTime();
}


How would I write a unit test to check the value returned by this function is the same as the expected value without using the same logic to generate the expected value?

Answer

See other answer for recommendation to use JodaTime or Java 8. However this can be done using java.util.Calendar.

The key is to change your method to pass in the date rather than let it assume the current time. Perhaps consider renaming this method too to reflect its new semantics, see Andreas suggestion of getFirstOfPreviousMonth.

You would need to call this as getFirstOfLastMonth(new Date()) to preserve existing behaviour, perhaps even with default method

public static Date getFirstOfLastMonth() {
     return getFirstOfPreviousMonth(new Date());
}

public static Date getFirstOfPreviousMonth(Date now) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(now);
    cal.add(Calendar.MONTH, -1);
    cal.set(Calendar.DAY_OF_MONTH, 1);

    return cal.getTime();
}

Then some tests, you can use Calendar to inspect the result:

@Test
public void previousYear() {
    Calendar input = Calendar.getInstance();
    input.clear();
    input.set(2009, Calendar.JANUARY, 5);

    Date result = getFirstOfLastMonth(input.getTime());

    Calendar output = Calendar.getInstance();
    output.setTime(result);
    assertThat(output.get(Calendar.YEAR), is(2008));
    assertThat(output.get(Calendar.MONTH), is(Calendar.DECEMBER));
    assertThat(output.get(Calendar.DAY_OF_MONTH), is(1));
}