使用模拟服务和日期时间测试随机失败
Test With Mocked Service And DateTime Fail Randomly
我有一个在 Bamboo 上随机失败的测试。这个比率就像每 10 个构建中有 1 个失败。它在我的本地环境中从未失败。
这里简化了我的服务:
public final class TripAdvisorSwitchServiceImpl implements TripAdvisorSwitchService{
private FfxProperties ffxProperties = FfxProperties.getInstance();
private DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssZ");
@Reference
private DateTimeService dateTimeService;
private static boolean forceEnable;
@Override
public boolean isEnabled() {
if (forceEnable) {
return true;
}
String endDateStr = ffxProperties.get("tripadvisor.endDate");
DateTime endDate;
try {
endDate = dateTimeFormatter.parseDateTime(endDateStr);
} catch (IllegalArgumentException e) {
LOG.error("Date format is wrong: {}", endDateStr);
return true;
}
return dateTimeService.getCurrentDateTime().isBefore(endDate);
}
}
这是我的随机失败测试:
@RunWith(PowerMockRunner.class)
@PrepareForTest(FfxProperties.class)
public class TripAdvisorSwitchServiceImplTest {
private DateTimeZone utcTimezone = DateTimeZone.forTimeZone(TimeZone.getTimeZone("UTC"));
@InjectMocks
private TripAdvisorSwitchServiceImpl tripAdvisorSwitchService;
@Mock
FfxProperties ffxProperties;
@Mock
DateTimeService dateTimeService;
@Before
public void setup() throws IllegalAccessException {
MockitoAnnotations.initMocks(this);
mockStatic(FfxProperties.class);
when(FfxProperties.getInstance()).thenReturn(ffxProperties);
}
@Test
public void tripAdvisorShouldBeDisabledAfterTheEndDate() {
when(ffxProperties.get("tripadvisor.endDate")).thenReturn("2010-09-14T14:00:00+0000");
when(dateTimeService.getCurrentDateTime()).thenReturn(new DateTime(2016, 9, 14, 14, 1, 0, 0, utcTimezone));
assertFalse("It should be disabled", tripAdvisorSwitchService.isEnabled());
}
}
非常感谢任何帮助。
它到底是怎么失败的?在这个例子中,我没有看到 ffxProperties 或 dateTimeService 被注入,我可以确认这只是因为你在发布时简化了问题吗?
我还没有看到问题,但通常当某些东西在我的盒子上总是成功但在构建盒子上周期性地失败时,时间问题正在发挥作用,我确实看到了时间,所以我对此表示怀疑。
但到目前为止,我的第一个猜测是这些字段没有被注入,或者以某种方式 return 以某种方式调整当前时间 - 如果它足够快,也许两个调用 return失败的相同日期时间?您可以通过设置断点或记录并确认日期时间是否符合您的想法来进行测试。
此问题是由于使用静态字段 forceEnable
(由其他测试操纵)以及并行执行来自 Bamboo 的测试引起的。
我有一个在 Bamboo 上随机失败的测试。这个比率就像每 10 个构建中有 1 个失败。它在我的本地环境中从未失败。
这里简化了我的服务:
public final class TripAdvisorSwitchServiceImpl implements TripAdvisorSwitchService{
private FfxProperties ffxProperties = FfxProperties.getInstance();
private DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssZ");
@Reference
private DateTimeService dateTimeService;
private static boolean forceEnable;
@Override
public boolean isEnabled() {
if (forceEnable) {
return true;
}
String endDateStr = ffxProperties.get("tripadvisor.endDate");
DateTime endDate;
try {
endDate = dateTimeFormatter.parseDateTime(endDateStr);
} catch (IllegalArgumentException e) {
LOG.error("Date format is wrong: {}", endDateStr);
return true;
}
return dateTimeService.getCurrentDateTime().isBefore(endDate);
}
}
这是我的随机失败测试:
@RunWith(PowerMockRunner.class)
@PrepareForTest(FfxProperties.class)
public class TripAdvisorSwitchServiceImplTest {
private DateTimeZone utcTimezone = DateTimeZone.forTimeZone(TimeZone.getTimeZone("UTC"));
@InjectMocks
private TripAdvisorSwitchServiceImpl tripAdvisorSwitchService;
@Mock
FfxProperties ffxProperties;
@Mock
DateTimeService dateTimeService;
@Before
public void setup() throws IllegalAccessException {
MockitoAnnotations.initMocks(this);
mockStatic(FfxProperties.class);
when(FfxProperties.getInstance()).thenReturn(ffxProperties);
}
@Test
public void tripAdvisorShouldBeDisabledAfterTheEndDate() {
when(ffxProperties.get("tripadvisor.endDate")).thenReturn("2010-09-14T14:00:00+0000");
when(dateTimeService.getCurrentDateTime()).thenReturn(new DateTime(2016, 9, 14, 14, 1, 0, 0, utcTimezone));
assertFalse("It should be disabled", tripAdvisorSwitchService.isEnabled());
}
}
非常感谢任何帮助。
它到底是怎么失败的?在这个例子中,我没有看到 ffxProperties 或 dateTimeService 被注入,我可以确认这只是因为你在发布时简化了问题吗?
我还没有看到问题,但通常当某些东西在我的盒子上总是成功但在构建盒子上周期性地失败时,时间问题正在发挥作用,我确实看到了时间,所以我对此表示怀疑。
但到目前为止,我的第一个猜测是这些字段没有被注入,或者以某种方式 return 以某种方式调整当前时间 - 如果它足够快,也许两个调用 return失败的相同日期时间?您可以通过设置断点或记录并确认日期时间是否符合您的想法来进行测试。
此问题是由于使用静态字段 forceEnable
(由其他测试操纵)以及并行执行来自 Bamboo 的测试引起的。