Java Mockito何时返回对象创建 [英] Java Mockito when-return on Object creation

查看:170
本文介绍了Java Mockito何时返回对象创建的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试测试计算年龄的课程.计算年龄的方法如下:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆