Java Mockito何时返回对象创建 [英] Java Mockito when-return on Object creation
问题描述
我正在尝试测试计算年龄的课程.计算年龄的方法如下:
I'm trying to test a class that calculates age. The method that calculates the age looks like this:
public static int getAge(LocalDate birthdate) {
LocalDate today = new LocalDate();
Period period = new Period(birthdate, today, PeriodType.yearMonthDay());
return period.getYears();
}
因为我希望JUnit与时间无关,所以我希望today
变量始终为2016年1月1日.为此,我尝试采用Mockito.when
路线,但遇到了麻烦.
Since I want the JUnit to be time-independent I want the today
variable to always be January 1, 2016. To do this I tried going the Mockito.when
route but am running into trouble.
我首先有这个:
public class CalculatorTest {
@Before
public void setUp() throws Exception {
LocalDate today = new LocalDate(2016,1,1);
Mockito.when(new LocalDate()).thenReturn(today);
}
}
但是我得到了这个错误:
But to that I got this error:
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
Mocking methods declared on non-public parent classes is not supported.
2. inside when() you don't call method on mock but on some other object.
因此,我然后尝试在Calculator类中创建一个方法,以返回当前日期,如下所示:
So then I tried to make a method inside the Calculator class to return the current date like so:
public static LocalDate getCurrentDate() {
return new LocalDate();
}
public static int getAge(LocalDate birthdate) {
LocalDate today = getCurrentDate();
Period period = new Period(birthdate, today, PeriodType.yearMonthDay());
return period.getYears();
}
这样我就可以做到:
public class CalculatorTest {
@Before
public void setUp() throws Exception {
CalculatorTest mock = Mockito.mock(CalculatorTest.class);
LocalDate today = new LocalDate(2016,1,1);
Mockito.when(mock.getCurrentDate()).thenReturn(today);
}
}
但是,我得到了完全相同的问题.那么,关于何时触发年龄计算如何返回预定义的本地日期对象的任何想法?
But to that I get the exact same problem. So any ideas on how to return a predefined localdate object whenever the age calculation is triggered?
推荐答案
我建议您使用Joda的org.joda.time.LocalDate而不是java.time.LocalDate
.
Instead of mocking, I'd suggest using Joda's DateTimeUtils to "freeze" the time. You would also need to use org.joda.time.LocalDate
instead of java.time.LocalDate
in your application code.
public class CalculatorTest {
@Before
public void setUp() throws Exception {
DateTimeUtils.setCurrentMillisFixed(new LocalDate(2016,1,1).toDateTimeAtStartOfDay().getMillis());
}
@After
public void tearDown() {
DateTimeUtils.setCurrentMillisSystem();
}
}
对于纯Java,请考虑在此处中描述的一些方法,特别是注入Clock
或使用PowerMock.
For pure Java, consider some approaches described here, particularly, injecting a Clock
or using PowerMock.
注入Clock
与Joda示例非常相似.您只需要维护自己的静态Clock
.您的应用程序代码如下所示:
Injecting a Clock
is quite similar to the Joda example; you just need to maintain your own static Clock
. Your application code would look like this:
static Clock appClock = Clock.systemDefaultZone();
public static int getAge(LocalDate birthdate) {
LocalDate today = LocalDate.now(appClock);
Period period = new Period(birthdate, today, PeriodType.yearMonthDay());
return period.getYears();
}
测试会像这样冻结时间:
And the test would freeze the time like this:
public class CalculatorTest {
@Before
public void setUp() {
appClock = Clock.fixed(LocalDate(2016,1,1).toDateTimeAtStartOfDay(), ZoneId.systemDefault());
}
@After
public void tearDown() {
appClock = Clock.systemDefaultZone();
}
}
这篇关于Java Mockito何时返回对象创建的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!