Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.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:如何模拟Calendar.getInstance()?_Java_Date_Junit_Calendar_Mocking - Fatal编程技术网

java:如何模拟Calendar.getInstance()?

java:如何模拟Calendar.getInstance()?,java,date,junit,calendar,mocking,Java,Date,Junit,Calendar,Mocking,在我的代码中,我有如下内容: private void doSomething() { Calendar today = Calendar.getInstance(); .... } interface Utility { Date getDate(); } Utilities implements Utility { public Date getDate() { return Calendar.getInstance().getTime

在我的代码中,我有如下内容:

private void doSomething() {
   Calendar today = Calendar.getInstance();
   ....
}
interface Utility {

    Date getDate();
}

Utilities implements Utility {


    public Date getDate() {

        return Calendar.getInstance().getTime();
    }

}

如何在junit测试中“模拟”它以返回特定的日期?

不要模拟它,而是引入一个可以模拟的方法来获取日期。大概是这样的:

private void doSomething() {
   Calendar today = Calendar.getInstance();
   ....
}
interface Utility {

    Date getDate();
}

Utilities implements Utility {


    public Date getDate() {

        return Calendar.getInstance().getTime();
    }

}
然后,您可以将其注入到类中,或者只使用一个helper类和一组静态方法以及接口的load方法:

public class AppUtil {

    private static Utility util = new Utilities();

    public static void load(Utility newUtil) {

         this.util = newUtil;
    }

    public static Date getDate() {

        return util.getDate();
    }

}
然后在应用程序代码中:

private void doSomething() {
   Date today = AppUtil.getDate();
   ....
}
然后,您可以在测试方法中加载一个模拟接口

@Test
public void shouldDoSomethingUseful() {
     Utility mockUtility = // .. create mock here
     AppUtil.load(mockUtility);

     // .. set up your expectations

     // exercise the functionality
     classUnderTest.doSomethingViaAPI();

     // ... maybe assert something 

}

另请参见和

在我看来,您有三个明智的选择:

  • Calendar
    实例插入到当天设置的任何方法/类中

    专用作废方法(最终日历校准)
    {
    Date today=cal.getTime();
    }

  • 使用而不是
    日历
    。这不是一个选择,而是一个建议,因为JodaTime会让你的生活轻松很多。这一次您仍然需要将其注入到方法中

    DateTime dt=newdatetime()

    datejdkdate=dt.toDate()

  • 日历
    包装在允许您获取时间的某个界面内。然后,您只需模拟该接口,并让它返回一个常量
    Date

    datetoday=calendarInterfaceInstance.getCurrentDate()


  • 使用返回
    Calendar.getInstance()
    的方法
    getCalendar
    编写一个名为
    DateHelper
    的类。重构您正在测试的类,使其具有类型为
    DateHelper
    的成员变量,以及注入该成员变量的构造函数。在测试中使用该构造函数,注入一个模拟的
    DateHelper
    ,其中
    getCalendar
    已被存根以返回一些已知的日期。

    您可以使用JMockit模拟它。在这里,您可以看到如何做到这一点:。

    您可以使用PowerMock结合Mockito对其进行模拟:

    在你班上最重要的是:

    @RunWith(PowerMockRunner.class)
    @PrepareForTest({ClassThatCallsTheCalendar.class})
    
    成功的关键是,您必须将使用Calendar的类放在PrepareForest中,而不是Calendar本身,因为它是一个系统类。(我个人在找到这个之前已经搜索了很多次)

    然后嘲笑本身:

    mockStatic(Calendar.class);
    when(Calendar.getInstance()).thenReturn(calendar);
    

    使用Mockito和PowerMockito:

    Calendar endOfMarch = Calendar.getInstance();
    endOfMarch.set(2011, Calendar.MARCH, 27);
    PowerMockito.mockStatic(Calendar.class);
    Mockito.when(Calendar.getInstance()).thenReturn(endOfMarch);
    

    有关完整代码,请参阅。

    该行无法编译!
    today
    是类成员(字段)还是方法中的局部变量?方法中的局部变量同一问题的现代版本(带答案):Joda Time的
    DateTimeUtils
    类具有为所有其他Joda Time对象设置当前时间的静态方法。这对于将时间设置为某个特定的时刻非常有用,例如用于测试。@Jesper-是的,这是正确的,我忽略了一点,谢谢大家。我听从了你的建议,搬到了JodaTime。顺便说一句,它可以很容易地解决这样的问题:DateTimeUtils.setCurrentMillisFixed(newdatetime(2012,2,14,13,43,21).getMillis());要使mockStatic()方法工作,您包括哪些依赖项?对不起,我应该这么说。我使用import static导入PowerMockito的mockStatic方法。查看powermock mockito的这个依赖项:你让我开心!