Junit 操纵模拟日历对象以返回特定日期
我正在使用Calendar对象来确定是否根据当前的日/小时值增加系统的工作负载。鉴于此对象使用静态方法,我将使用PowerMock使用以下注释模拟静态方法:Junit 操纵模拟日历对象以返回特定日期,junit,powermock,easymock,Junit,Powermock,Easymock,我正在使用Calendar对象来确定是否根据当前的日/小时值增加系统的工作负载。鉴于此对象使用静态方法,我将使用PowerMock使用以下注释模拟静态方法: @RunWith(PowerMockRunner.class) @PrepareForTest({ Calendar.class }) 虽然我的逻辑需要工作,但测试的代码非常简单,我知道: public void determineDefaultMaximumScans() throws ParseException{ parseTi
@RunWith(PowerMockRunner.class)
@PrepareForTest({ Calendar.class })
虽然我的逻辑需要工作,但测试的代码非常简单,我知道:
public void determineDefaultMaximumScans() throws ParseException{
parseTime();
Calendar cal = Calendar.getInstance();
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
System.out.println(cal.get(Calendar.DAY_OF_WEEK));
if(dayOfWeek == (Calendar.SATURDAY) || dayOfWeek == (Calendar.SUNDAY)){
setDefaultMax(calculateNewDefaultMax(getDefaultMax()));
System.out.println("defaultMax increased by 20%");
} else {
if(currentTime.after(afterHoursBegin) && currentTime.before(afterHoursEnd)){
System.out.println("Not afterhours. Maintaining current maximum.");
setDefaultMax(defaultMax);
System.out.println("Current Maximum number of scans: " + getDefaultMax());
}
}
}
我的测试用例如下所示:
@SuppressWarnings("static-access")
@Test
public void testDetermineMaximumScans() throws ParseException{
PowerMock.mockStatic(Calendar.class);
String beginningTime = "18:00";
String endingTime = "05:00";
mockAfterHoursBegin = parser.parse(beginningTime);
mockAfterHoursEnd = parser.parse(endingTime);
mockCurrentTime = parser.parse(parser.format(new Date()));
EasyMock.expect(Calendar.getInstance()).andReturn(mockCalendar);
EasyMock.expect(mockCalendar.get(Calendar.DAY_OF_WEEK)).andReturn(6);
EasyMock.replay(mocks);
offHourMaximumCalculator.determineDefaultMaximumScans();
EasyMock.verify(mocks);
}
到目前为止,我所有返回特定值的尝试都会导致以下断言错误。现在我模糊地理解了它为什么返回默认值,但我不明白为什么我不能强制执行该值,或者如何绕过这个期望值。总的来说,嘲弄对我来说仍然是一个令人沮丧的谜。我错过了什么
java.lang.AssertionError:
Expectation failure on verify:
Calendar.get(7): expected: 1, actual: 0
mock相当简单。但是想要模拟静态方法是一项追求复杂性的艰巨任务。我一般不建议模仿日历之类的东西。如果你用它做了一些奇怪和复杂的事情,只需封装在一些你可以轻松测试和模拟的东西中 事实上,我们几乎从不使用Calendar.getInstance。它根据区域设置返回一些内容。但很少有人不想要一个特定的日历,即格里高利安日历。那就做新的格雷戈里安·卡伦达吧 但是无论如何,添加一个受保护的方法
protected Calendar newCalendar() {
return Calendar.getInstance(); // or new GregorianCalendar()
}
将需要2分钟,然后一个简单的局部模拟将完成此任务
最后,我也不建议使用日历。java 8中的java.util.date中有一个更好的API
所有这些都表明,以下是你应该怎么做。Calendar是一个系统类,所以您需要遵循下面解释的实际特定路径
仅供参考:Calendar是一个非常古老的类,现在是遗留类,几年前被ZonedDateTime等java.time类取代。
@RunWith(PowerMockRunner.class)
@PrepareForTest(Calendar.class)
public class MyTest {
@Test
public void testDetermineMaximumScans() throws ParseException {
PowerMock.mockStatic(Calendar.class);
Calendar calendar = mock(Calendar.class);
EasyMock.expect(Calendar.getInstance()).andReturn(calendar);
EasyMock.expect(calendar.get(Calendar.DAY_OF_WEEK)).andReturn(6);
// really important to replayAll to replay the static expectation
PowerMock.replayAll(calendar);
assertThat(Calendar.getInstance().get(Calendar.DAY_OF_WEEK)).isEqualTo(6);
// and verifyAll is you want to verify that the static call actually happened
PowerMock.verifyAll();
}
}