java:如何模拟日历.getInstance()?

dm7nw8vv  于 2023-01-29  发布在  Java
关注(0)|答案(7)|浏览(148)

在我的代码中,我有这样的代码:

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

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

bhmjp9jg

bhmjp9jg1#

您可以结合使用PowerMock和Mockito来模拟它:
在您的类中名列前茅:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ClassThatCallsTheCalendar.class})

成功的关键是必须将使用Calendar的类放在PrepareForTest中,而不是放在Calendar本身中,因为它是一个系统类(我个人在找到这个类之前搜索了很多)。
然后是嘲笑本身:

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

m0rkklqb2#

在我看来,你有三个明智的选择:
1.将Calendar示例注入到当天设置的任何方法/类中。
private void method(final Calendar cal) { Date today = cal.getTime(); }
1.使用JodaTime而不是Calendar。这不是一个选项,而是一个建议,因为JodaTime会让您的工作变得更加轻松。您仍然需要将此时间注入到方法中。
DateTime dt = new DateTime();
Date jdkDate = dt.toDate();
1.将Calendar Package 在某个允许获取时间的接口中,然后模拟该接口并让它返回一个常量Date
Date today = calendarInterfaceInstance.getCurrentDate()

t3irkdon

t3irkdon3#

不要嘲笑它,而是引入一个你可以嘲笑的获取日期的方法,比如:

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 

}

另请参见Should you only mock types you own?Test smell - everything is mocked

oxosxuxt

oxosxuxt4#

使用Mockito和PowerMockito:

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

有关完整代码,请参阅link

u4vypkhs

u4vypkhs5#

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

q5iwbnjs

q5iwbnjs6#

您可以使用JMockit进行mockit。在这里您可以看到如何执行此操作:Mock Java Calendar - JMockit vs Mockito.

8yparm6h

8yparm6h7#

避免使用Calendar.getInstance(),只使用Mockito方法返回您喜欢的结果。例如:

@Test
fun italianLocale_returnsItalianFormatDate() {
    val calendar: Calendar = Mockito.mock(Calendar::class.java)
    Mockito.`when`(calendar.get(Calendar.DAY_OF_MONTH)).thenReturn(27)
    Mockito.`when`(calendar.get(Calendar.YEAR)).thenReturn(2023)
    Mockito.`when`(calendar.get(Calendar.MONTH)).thenReturn(1)
    val formatted = calendar.toReadableDate()
    assert(formatted == "27/01/2023")
}

使用以下命令在Gradle文件中导入Mockito:

testImplementation ("org.mockito.kotlin:mockito-kotlin:x.x.x")

或者(如果您使用的是Groovy)

testImplementation "org.mockito.kotlin:mockito-kotlin:x.x.x"

相关问题