测试时间相关的服务方法

时间:2012-05-08 23:31:58

标签: java testing junit mocking integration-testing

我正在尝试使用查找数据库表中当前“处理周期”的方法为服务编写集成测试。但是,并不总是有一个活动的处理周期,因此该方法可能返回null(有几周没有处理发生)。我想为这个方法编写一个JUnit测试,但由于它不会总是返回一个值,我会得到不同的结果,具体取决于我运行测试的时间。

期间对象和服务如下:

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 */ }
}

PeriodService的实例由Spring应用程序上下文管理,我的JUnit测试使用SpringJUnit4ClassRunner构建测试上下文并为测试提供服务对象。我的JUnit测试目前看起来像:

@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));
    }
}

但是,如果在处理期间没有运行测试,那似乎不会有太大帮助。我怎样才能有意义地测试getCurrentPeriod方法实际上从数据库获得正确的时间段?我应该嘲笑数据库吗?我还想实际对数据库执行查询,以帮助确保SQL有效。

1 个答案:

答案 0 :(得分:1)

而不是在我的代码new Date()getCurrentTimeMillis()等中使用。我总是使用包含我需要的所有时间相关方法的时间提供程序。

interface TimeProvider {
  Date getDate();
  int getCurrentQuarter();
  ...
}
生产实施是显而易见的。但是,对于测试,您可以放置​​所需的任何提供程序,以便在测试中随时设置。它适用于春天。但它只有在测试不使用它自己的内部时钟(睡眠,锁定,石英等)的代码时才有效。

看起来很适合您的示例,但您必须重构您的生产代码