我需要模拟所需的类并获得所需的日期结果。
我已经尝试过模拟DateFormat类中的format()函数但是没有用。
class XYZ {
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMddHHmmss");
private static final TimeZone UTC = TimeZone.getTimeZone("UTC");
public void buildStr(StringBuilder str){
DATE_FORMAT.setTimeZone(UTC);
Date date = getDate();
str.append(DATE_FORMAT.format(date));
}
private Date getDate(){
return new Date();
}
}
在这段代码中我希望星号附加“20190430000000”(正是这个值),但我得到的是当前的UTC时间。
您正在使用几年前由JSR 310中定义的现代java.time类取代的可怕日期时间类。
Clock
java.time类采用可选的Clock
参数。传递Clock
对象以及测试所需的行为。 Clock
类具有提供几种特殊行为的静态方法。这些包括固定时刻,在真正时钟前后设置一定时间的滚动时刻,以及改变的节奏,例如在整个分钟上递增。
Stack Overflow上已经多次介绍过这个问题。搜索以了解更多信息。
LocalDate ld = LocalDate.of( 2019 , Month.APRIL , 30 ) ;
ZoneId z = ZoneId.of( "America/Edmonton" ) ;
ZonedDateTime zdt = ld.atStartOfDay( z ) ;
Instant instant = zdt.toInstant() ;
Clock clock = Clock.fixed( instant , z ) ;
现在在测试中注入clock
对象。
ZonedDateTime zdt = ZonedDateTime.now( clock ) ;
如果您想要一个真正的时钟,请使用:
Clock clock = Clock.system( z ) ;
您可以使用固定日期
LocalDate date = LocalDate.parse("20190430000000", DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
此代码示例适用于java8或更高版本。
EDIT1
假设:您希望编写一个使用固定日期但在生产中使用当前日期的测试。您可以使用JUnit,某种依赖注入和Mockito。
这是一个不能直接编译的抽象示例。
class XYZ {
@Inject
private DateProvider dateProvider;
public void buildStr(StringBuilder str){
LocalDate date = dateProvider.getDate();
// do something with date
}
}
class DateProvider {
public Date getDate() {
return new Date();
}
}
class XYZTest {
@Mock
private DateProvider dateProvider;
@InjectMocks
private XYZ xyz;
@Test
public void test() {
LocalDate fixedDate = LocalDate.parse("20190430000000", DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
when(dateProvider.getDate()).thenReturn(fixedDate);
StringBuilder builder = new StringBuilder();
xyz.buildStr(builder);
// verify builder contains what you expect
}
}
在您的服务类中,您定义了一个提供日期的附加组件(此处为DateProvider
)。在测试中,您可以通过Mocktio提供的注释@InjectMocks
获得服务的可测试实例。它将使用@Mock
注释的任何字段作为模拟注入您的可测试实例。在您的测试中,您可以定义when().thenReturn()
应该执行的模拟操作。您的生产代码将使用DateProvider
的实际实现,并获得当前日期。