1

I'm trying to write an integration test for a service with a method that looks up the current "processing period" in a database table. However, there is not always an active processing period, so the method may return null (there are weeks where no processing occurs). I would like to write a JUnit test for this method, but since it won't always return a value, I'll get different results depending on when I run the test.

The period object and service looks like:

public interface ProcessingPeriod {
    int getSeqno();
    Date getStart();
    Date getEnd();
}

public class PeriodService {
    /* Look up the current period; if not currently in a period, return null */
    public ProcessingPeriod getCurrentPeriod() { /* execute a sql query */ }

    /* Look up the current period; if not currently in a period, get the next upcoming period */
    public ProcessingPeriod getCurrentOrNextPeriod() { /* execute a sql query */ }

    /* Look up the current period; if not currently in a period, get the most recent period */
    public ProcessingPeriod getCurrentOrPreviousPeriod() { /* execute a sql query */ }
}

An instance of PeriodService is managed by a Spring application context, and my JUnit test uses the SpringJUnit4ClassRunner to construct a test context and provide the service object to the test. My JUnit test currently looks like:

@Test
public void testGetCurrentPeriod() {
    ProcessingPeriod period = service.getCurrentPeriod();
    if (period != null) {
        Date now = new Date();
        assertThat(period.getStart(), lessThanOrEqualTo(now));
        assertThat(period.getEnd(), greaterThanOrEqualTo(now));
    }
}

But that doesn't seem like it's going to help much if the test isn't run during a processing period. How can I meaningfully test that the getCurrentPeriod method actually gets the right period from the database? Should I be mocking the database? I had also wanted to actually execute the query against the database to help ensure the SQL is valid.

assylias
  • 321,522
  • 82
  • 660
  • 783
matts
  • 6,738
  • 1
  • 33
  • 50
  • 1
    An example of why writing code that returns null is considered a no-no. ;-) – Phil Freihofner May 08 '12 at 23:39
  • possible related questions: http://stackoverflow.com/questions/9731526/how-to-test-a-feature-that-depends-on-date-events-happen, http://stackoverflow.com/questions/2284279/how-to-test-logic-which-is-dependent-on-current-date, http://stackoverflow.com/questions/5092017/junit-with-new-date – k3b May 09 '12 at 13:35
  • Its always better to run test using sample test data, before your test run in your setup create some test data , run test, and in finally delete those records. – Sajan Chandran May 10 '12 at 13:14

1 Answers1

1

instead of using in my code new Date(), getCurrentTimeMillis(), etc. i always use a time provider that contains all time related methods i need.

interface TimeProvider {
  Date getDate();
  int getCurrentQuarter();
  ...
}

production implementation is obvious. for tests, however, you can put any provider you need so you can set any time you like in tests. it works good with spring. but it works only when you test code that doesn't use it's own internal clock (sleep, lock, quartz, etc).

looks like it fits your example but you will have to refactor your production code

piotrek
  • 13,982
  • 13
  • 79
  • 165
  • Thanks, this may be possible; though the current query is using the current datetime from the database, since we treat it as the authority throughout the organization. – matts May 10 '12 at 16:36
  • if db date is necessary then you should refactor the query so it takes the date as a parameter – piotrek May 10 '12 at 17:11