我的团队收到了一个新项目。该项目有一堆没有通过的测试。用他们的话说,所有的测试都应该通过。在调查问题后,我发现存在一个共同的问题。大多数失败的测试创建Timestamp
并使用它,但预期和实际日期不一样。差别只有一个小时。旧开发团队一直在GMT + 1区工作,我们的工作是GMT + 2。
为什么会这样?
修改:
我有一个测试,它创建实体Rating
并设置一堆属性。例如:
rating.setValidFromDate(new Timestamp(1459841866798L));
然后测试断言一个预期的String常量和rating.toString()
正如我所说,差异恰好是1小时
编辑2 :
@Test
public void testToString() {
Rating rating = new Rating();
rating.setValidFromDate(new Timestamp(1459841866798L));
assertEquals("Rating{validFromDate='2016-04-05 09:37:46'}", rating.toString());
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(Rating.class.getSimpleName());
builder.append("{");
builder.append("validFromDate='" + DateHelper.getStringFromDate(validFromDate) + "'");
builder.append("}");
return builder.toString();
}
public static String getStringFromDate(Date dateValue) {
String strDate = "";
if (dateValue != null) {
DateFormat dateFormat = new SimpleDateFormat(Constants.DATETIME_FORMAT);
strDate = dateFormat.format(dateValue);
}
return strDate;
}
我决定给你解决这个问题的方法。
阅读之后:java.sql.Timestamp: changing timezone of Timestamp我找到了一种操纵测试时区的方法。所以我决定编写一个JUnit规则,它将对我的所有测试都这样做。
我写了以下声明:
public class GermanTimeZoneStatement extends Statement {
private final Statement base;
public GermanTimeZoneStatement(Statement base) {
super();
this.base = base;
}
@Override
public void evaluate() throws Throwable {
TimeZone.setDefault(TimeZone.getTimeZone("Europe/Berlin"));
base.evaluate();
}
}
之后我写了这条规则:
public class GermanTimeZoneRule implements TestRule {
public static GermanTimeZoneRule getInstance() {
return new GermanTimeZoneRule();
}
@Override
public Statement apply(Statement base, Description description) {
return new GermanTimeZoneStatement(base);
}
}
最后,我在我的测试中包含了这样的规则:
@Rule
public GermanTimeZoneRule germanTimeZoneRule = GermanTimeZoneRule.getInstance();
答案 0 :(得分:3)
您正在测试的代码与时区有关。它根据用户默认时区中的时间输出特定日期。这就是为什么它会给你不同的输出结果。
您需要返回该代码的规范,并检查这是否是预期的行为。如果是,您需要修改测试以考虑时区。如果它不是预期的行为,那么恭喜你,你的测试暴露了一个错误!