Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在对象创建时返回Java Mockito_Java_Junit_Mockito_Jodatime - Fatal编程技术网

在对象创建时返回Java Mockito

在对象创建时返回Java Mockito,java,junit,mockito,jodatime,Java,Junit,Mockito,Jodatime,我想测试一个计算年龄的类。计算年龄的方法如下所示: public static int getAge(LocalDate birthdate) { LocalDate today = new LocalDate(); Period period = new Period(birthdate, today, PeriodType.yearMonthDay()); return period.getYears(); } static Clock appClock = Clo

我想测试一个计算年龄的类。计算年龄的方法如下所示:

public static int getAge(LocalDate birthdate) {
    LocalDate today = new LocalDate();
    Period period = new Period(birthdate, today, PeriodType.yearMonthDay());
    return period.getYears();
}
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(); 
}
public class CalculatorTest {

    @Before
    public void setUp() {
       appClock = Clock.fixed(LocalDate(2016,1,1).toDateTimeAtStartOfDay(), ZoneId.systemDefault());
    }

    @After
    public void tearDown() {
       appClock = Clock.systemDefaultZone();
    }
}
因为我希望JUnit与时间无关,所以我希望
today
变量始终为2016年1月1日。为此,我试着走
Mockito.when
路线,但遇到了麻烦

我第一次做这个:

public class CalculatorTest {

    @Before
    public void setUp() throws Exception {
        LocalDate today = new LocalDate(2016,1,1);

        Mockito.when(new LocalDate()).thenReturn(today);
    }
}
但我有一个错误:

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类中创建一个方法来返回当前日期,如下所示:

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);
    }
}

但对于这一点,我得到了完全相同的问题。那么,在触发年龄计算时如何返回预定义的localdate对象呢

我建议用乔达的来“冻结”时间,而不是嘲笑。您还需要在应用程序代码中使用
org.joda.time.LocalDate
而不是
java.time.LocalDate

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,考虑一些方法,特别是,注入<代码>时钟<代码>或使用PosiMoCK。< /P> 注入

时钟
与Joda示例非常相似;您只需维护自己的静态
时钟
。您的应用程序代码如下所示:

public static int getAge(LocalDate birthdate) {
    LocalDate today = new LocalDate();
    Period period = new Period(birthdate, today, PeriodType.yearMonthDay());
    return period.getYears();
}
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(); 
}
public class CalculatorTest {

    @Before
    public void setUp() {
       appClock = Clock.fixed(LocalDate(2016,1,1).toDateTimeAtStartOfDay(), ZoneId.systemDefault());
    }

    @After
    public void tearDown() {
       appClock = Clock.systemDefaultZone();
    }
}
而测试会像这样冻结时间:

public static int getAge(LocalDate birthdate) {
    LocalDate today = new LocalDate();
    Period period = new Period(birthdate, today, PeriodType.yearMonthDay());
    return period.getYears();
}
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(); 
}
public class CalculatorTest {

    @Before
    public void setUp() {
       appClock = Clock.fixed(LocalDate(2016,1,1).toDateTimeAtStartOfDay(), ZoneId.systemDefault());
    }

    @After
    public void tearDown() {
       appClock = Clock.systemDefaultZone();
    }
}

与其嘲笑,我建议用乔达的来“冻结”时间。您还需要在应用程序代码中使用
org.joda.time.LocalDate
而不是
java.time.LocalDate

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,考虑一些方法,特别是,注入<代码>时钟<代码>或使用PosiMoCK。< /P> 注入

时钟
与Joda示例非常相似;您只需维护自己的静态
时钟
。您的应用程序代码如下所示:

public static int getAge(LocalDate birthdate) {
    LocalDate today = new LocalDate();
    Period period = new Period(birthdate, today, PeriodType.yearMonthDay());
    return period.getYears();
}
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(); 
}
public class CalculatorTest {

    @Before
    public void setUp() {
       appClock = Clock.fixed(LocalDate(2016,1,1).toDateTimeAtStartOfDay(), ZoneId.systemDefault());
    }

    @After
    public void tearDown() {
       appClock = Clock.systemDefaultZone();
    }
}
而测试会像这样冻结时间:

public static int getAge(LocalDate birthdate) {
    LocalDate today = new LocalDate();
    Period period = new Period(birthdate, today, PeriodType.yearMonthDay());
    return period.getYears();
}
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(); 
}
public class CalculatorTest {

    @Before
    public void setUp() {
       appClock = Clock.fixed(LocalDate(2016,1,1).toDateTimeAtStartOfDay(), ZoneId.systemDefault());
    }

    @After
    public void tearDown() {
       appClock = Clock.systemDefaultZone();
    }
}

我总是使用自己的
TimeFactory
在应用程序中检索当前日期。通过这种方式,我可以灵活地操作它(在JUnit测试期间)。这就是TimeFactory的外观:

public final class TimeFactory {

    static int offsetAmount = 0;
    static TemporalUnit offsetUnit = ChronoUnit.MILLIS;

    public static LocalDateTime getLocalDateTimeNow() {
        return LocalDateTime.now().plus(offsetAmount, offsetUnit);
    }

    public static void reset() {
        offsetAmount = 0;
    }

    public static void travelToPast(int amount, TemporalUnit unit) {
        offsetAmount = amount * -1;
        offsetUnit = unit;
    }

    public static void travelToFuture(int amount, TemporalUnit unit) {
        offsetAmount = amount;
        offsetUnit = unit;
    }
}
使用此TimeFactory,我可以轻松完成时间旅行:

// start test
TimeFactory.travelToPast(10, ChronoUnit.HOURS);
// continue tests
TimeFactory.reset();
// check that things have happend in the past.

您可以扩展此代码以确定时间。

我总是使用自己的
TimeFactory
在应用程序中检索当前日期。通过这种方式,我可以灵活地操作它(在JUnit测试期间)。这就是TimeFactory的外观:

public final class TimeFactory {

    static int offsetAmount = 0;
    static TemporalUnit offsetUnit = ChronoUnit.MILLIS;

    public static LocalDateTime getLocalDateTimeNow() {
        return LocalDateTime.now().plus(offsetAmount, offsetUnit);
    }

    public static void reset() {
        offsetAmount = 0;
    }

    public static void travelToPast(int amount, TemporalUnit unit) {
        offsetAmount = amount * -1;
        offsetUnit = unit;
    }

    public static void travelToFuture(int amount, TemporalUnit unit) {
        offsetAmount = amount;
        offsetUnit = unit;
    }
}
使用此TimeFactory,我可以轻松完成时间旅行:

// start test
TimeFactory.travelToPast(10, ChronoUnit.HOURS);
// continue tests
TimeFactory.reset();
// check that things have happend in the past.

您可以扩展此代码来确定时间。

我建议您使用技巧来测试您的方法:

public static int getAge(LocalDate currDate, LocalDate birthdate) {
    Period period = new Period(birthdate, currDate, PeriodType.yearMonthDay());
    return period.getYears();
}

public static int getAge(LocalDate birthdate) {
    return getAge(new LocalDate (), birthdate);
}

我建议您使用技巧来测试您的方法:

public static int getAge(LocalDate currDate, LocalDate birthdate) {
    Period period = new Period(birthdate, currDate, PeriodType.yearMonthDay());
    return period.getYears();
}

public static int getAge(LocalDate birthdate) {
    return getAge(new LocalDate (), birthdate);
}

您是否尝试从
getCurrentDate
中删除
静态
修饰符?Mockito无法模拟静态方法。是否尝试从
getCurrentDate
中删除
static
修饰符?Mockito无法模拟静态方法。DateMidnight已被弃用,我应该改用
LocalDate
吗?@Richard你在想什么?不,我试过
DateMidnight
,intelliJ说它已被弃用。你是对的,我正在看一个早期版本
LocalDate
无法直接工作,因为它不能转换为
即时
。可以使用“一天开始”。让我更新一下。我刚刚尝试了这个方法,它成功了:
DateTimeUtils.setCurrentMillisFixed(newdatetime(2015,2,1,0,0).getMillis())
DateMidnight已被弃用,我应该改用
LocalDate
吗?@Richard你在想什么?不,我试过
DateMidnight
,intelliJ说它已被弃用。你是对的,我正在看一个早期版本
LocalDate
无法直接工作,因为它不能转换为
即时
。可以使用“一天开始”。让我更新一下。我刚刚尝试了这个方法,它成功了:
DateTimeUtils.setCurrentMillisFixed(newdatetime(2015,2,1,0,0).getMillis())