【问题标题】:Easymock using date expectationEasymock 使用日期期望
【发布时间】:2010-01-28 14:21:34
【问题描述】:

我正在使用easymock 模拟一个在其主体中有日期的方法,如下所示:

public void testedMethod() {
    ...
    if (doSomething(new Date())) {
    ...
}

我的测试是这样的:

public void testThatMethod() {
    ...
    expect(testedClass.testedMethod(new Date())).andReturn(false);
    ...
}

但是当我运行测试时,有时会出现如下错误:

意外的方法调用测试方法(2010 年 1 月 28 日星期四 09:45:13 GMT-03:00): 测试方法(Thu Jan 28 09:45:13 GMT-03:00 2010):预期:1,实际:0

我认为这是因为有时日期略有不同。我已经尝试了一些灵活的期望,但没有成功。有没有办法解决这个问题?

【问题讨论】:

标签: java date easymock


【解决方案1】:

我们经常面临类似的问题,这些是我看到的替代方案:

  1. 将日期作为参数提供给方法 (+) 快速更换 (-) 有点脏——当你只想使用“现在”时,它也会污染你的界面
  2. 从合作者“QueryCurrentDateProvider”中获取日期 (+) 还是很快 (+) 也可以被嘲笑 -> 你确定你使用相同的日期 (-) 为您需要执行类似操作的每个服务创建不必要的协作者
  3. 编写您自己的 EasyMock 参数匹配器,在其中抽象出您真正想做的事情 - 当您只对当天感兴趣时,而不是在您可以使用 commons DateUtils.isSameDay 之类的东西来运行它时 (+) 最干净的解决方案 (+) 没有更改您的生产代码 (-) 你必须编写自己的匹配器(虽然我不明白为什么 EasyMock 还没有)
  4. 将“new Date()”移至私有方法,然后使用类似 PowerMock 的方法模拟此方法 (+) 快速 (+) 对生产代码的小改动 (-) 引入 power mock 作为依赖项
  5. 将参数从日期更改为字符串,并在调用方法之前使用通用模式将日期转换为字符串 (+) 快速 (+) 测试站点上不需要额外的代码和库 (-) 您必须在调用方法之前格式化日期并在被调用方法中解析日期

所以这真的取决于你的个人喜好。当您经常使用当前时间戳时,我会推荐使用参数匹配器 - 因为这项投资会很快得到回报。

【讨论】:

    【解决方案2】:

    停止使用 new Date(),改用具有恒定时间的日历。

    //Declare the Calendar in your test method
    Calendar cal = Calendar.getInstance();
    cal.setTimeInMillis(0l);
    
    //receive the calendar to be used in testedClass constructor
    public void testedMethod() {
        ...
        if (doSomething(cal.getTime())) {
        ...
    }
    
    //use the same calendar to make the assertion
    public void testThatMethod() {
        ...
        expect(testedClass.(testedMethod(cal.getTime())).andReturn(false);
        ...
    }
    

    【讨论】:

    • 请注意 cal.setTimeInMillis(0l);将时间重置为 1970 年 1 月 1 日。如果您只想删除毫秒,请使用 cal.set(Calendar.MILLISECOND, 0);而是。
    【解决方案3】:

    我刚刚找到了这个帖子,它帮助我解决了一个我被困了一个小时的问题。

    以为我会分享我的 2 美分:

    如果您不关心日期值,只想知道它是一个 Date 对象,只需使用 EasyMock 的预定义匹配器:

    EasyMock.expect(objectMock.isPollingTimeOut(EasyMock.eq(600000L), EasyMock.isA(Date.class), EasyMock.eq(someMock))).andReturn(false);
    

    请记住,一旦您使用了匹配器,您就必须像我一样对您正在测试的方法中的所有参数使用匹配器。

    【讨论】:

    • 非常感谢,这个帮助了我。将此解决方案集成到 OP 的代码中:expect(testedClass.testedMethod(EasyMock.isA(Date.class))).andReturn(false);
    【解决方案4】:

    如果您能准确找出失败的原因,您可以编写自己的匹配器以更灵活地匹配日期。请参阅匹配器部分http://easymock.org/EasyMock2_2_Documentation.html

    【讨论】:

      【解决方案5】:

      可能是日期的毫秒部分不同。在创建日期对象之前,您可能需要使用 Calendar.set() 将其归零:

      Calendar myCalendar = Calendar.getInstance();
      myCalendar.set(Calendar.MILLISECOND, 0);
      Date testDate = myCalendar.getTime();
      

      但这是一个猜测:)

      【讨论】:

        【解决方案6】:

        使用自定义 EasyMock 匹配器进行松散的日期比较。这是一个示例,它将检查日期是否在一秒内。

        public class MyEasyMockMatchers {
        
            public static Date withinSecondOf(Date value){
                EasyMock.reportMatcher(new IArgumentMatcher() {
                    @Override
                    public boolean matches(Object argument) {
                        return argument instanceof Date
                                && Math.abs(((Date) argument).getTime() - value.getTime()) < Timer.ONE_SECOND;
                    }
        
                    @Override
                    public void appendTo(StringBuffer buffer) {
                        buffer.append(value.toString());
                    }
                });
                return null;
            }
        }
        

        那么在你的测试中使用:

        import static my.package.MyEasyMockMatchers.*;
        ...
        expect(testedClass.testedMethod(withinSecondOf(new Date())))
                .andReturn(false);
        

        请注意,当您使用一个匹配器时,您必须对整个期望使用匹配器。例如:

        expect(testedClass.testedMethod(42, "hello", new Date()))
                .andReturn(false);
        // becomes
        expect(testedClass.testedMethod(eq(42), eq("hello"), withinSecondOf(new Date())))
                .andReturn(false);
        

        见:https://easymock.org/user-guide.html#verification-expectations

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-12-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多