Java 测试时间相关服务方法
我正在尝试为一个服务编写一个集成测试,该测试使用一个在数据库表中查找当前“处理周期”的方法。但是,并不总是有一个活动的处理周期,因此该方法可能返回null(有几周没有处理)。我想为这个方法编写一个JUnit测试,但是因为它并不总是返回一个值,所以我会根据运行测试的时间得到不同的结果 时段对象和服务如下所示:Java 测试时间相关服务方法,java,testing,junit,mocking,integration-testing,Java,Testing,Junit,Mocking,Integration Testing,我正在尝试为一个服务编写一个集成测试,该测试使用一个在数据库表中查找当前“处理周期”的方法。但是,并不总是有一个活动的处理周期,因此该方法可能返回null(有几周没有处理)。我想为这个方法编写一个JUnit测试,但是因为它并不总是返回一个值,所以我会根据运行测试的时间得到不同的结果 时段对象和服务如下所示: public interface ProcessingPeriod { int getSeqno(); Date getStart(); Date getEnd();
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 */ }
}
@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));
}
}
PeriodService
的实例由Spring应用程序上下文管理,我的JUnit测试使用SpringJUnit4ClassRunner
构建测试上下文并向测试提供服务对象。我的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 */ }
}
@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有效。而不是在我的代码中使用新日期(),getCurrentTimeMillis()
等。我总是使用包含我所需的所有与时间相关的方法的时间提供程序
interface TimeProvider {
Date getDate();
int getCurrentQuarter();
...
}
生产实现是显而易见的。但是,对于测试,您可以放置所需的任何提供程序,以便可以在测试中设置任何时间。它与弹簧配合得很好。但它只有在测试不使用自身内部时钟(睡眠、锁定、石英等)的代码时才起作用
看起来它符合您的示例,但您必须重构生产代码,而不是在我的代码中使用新日期(),
getCurrentTimeMillis()
,等等。我总是使用包含所有需要的时间相关方法的时间提供程序
interface TimeProvider {
Date getDate();
int getCurrentQuarter();
...
}
生产实现是显而易见的。但是,对于测试,您可以放置所需的任何提供程序,以便可以在测试中设置任何时间。它与弹簧配合得很好。但它只有在测试不使用自身内部时钟(睡眠、锁定、石英等)的代码时才起作用
看起来它符合您的示例,但您必须重构生产代码一个示例,说明为什么编写返回null的代码被视为不允许的;-)可能的相关问题:,在设置中的测试运行之前,最好使用示例测试数据运行测试创建一些测试数据,运行测试,并在中最终删除这些记录。以下示例说明了为什么编写返回null的代码被视为“否”。-)可能的相关问题:,在设置中的测试运行之前,最好使用示例测试数据运行测试。请创建一些测试数据,运行测试,并最终删除这些记录。谢谢,这可能是可能的;虽然当前查询使用数据库中的当前日期时间,但我们将其视为整个组织的权限。如果需要db date,则应重构查询,使其将日期作为参数谢谢,这是可能的;虽然当前查询使用数据库中的当前日期时间,但我们将其视为整个组织的权限。如果需要db date,则应重构查询,使其将日期作为参数