【问题标题】:Can a JMock mock object return another mock object?JMock 模拟对象可以返回另一个模拟对象吗?
【发布时间】:2010-04-20 00:26:01
【问题描述】:

我正在使用 iBatis DAO 框架为应用程序编写测试。该应用程序在 java 1.4 环境中运行,所以我使用的是旧版本的一切(JDK 1.4、JUnit3、iBatis 2.3 和 JMock 1.2)。

在我的MockObjectTestCase 子类中我有这个测试

public void testInsert() throws Exception {
    Mock mockDao = mock(TblPpvFiltersDao.class);
    mockDao.expects(once()).method("insert");

    Mock mockDaoManager = mock(DaoManager.class);
    mockDaoManager.expects(once()).method("getDao")
            .with(eq(TblPpvFiltersDao.class))
            .will(returnValue((TblPpvFiltersDao) mockDao.proxy()));

    PpvFiltersService service = new PpvFiltersServiceImpl(
            (DaoManager) mockDaoManager.proxy());

    service.insert(new PpvFiltersVO());        
}

这应该验证服务对象会向DaoManager 请求DAO 对象并在其上调用insert 方法。测试失败并显示错误消息

...DynamicMockError: mockDaoManager: tried to return an incompatible value: 
   expected a com.ibatis.dao.client.Dao but returned a $Proxy0

尝试将mockDao 对象转换为com.ibatis.dao.client.Daocom.ibatis.dao.client.template.SqlMapDaoTemplateClassCastException 结尾。

我错过了什么?

更新:将代码转换为使用 JDK 1.6、JUnit 4 和 JMock2 没有任何变化。这段代码

@Test
public void testInsert() throws Exception {
    final PpvFiltersVO theFilter = new PpvFiltersVO(new Integer(42));
    final TblPpvFiltersDao mockDao = context.mock(TblPpvFiltersDao.class);
    final DaoManager mockDaoManager = context.mock(DaoManager.class);

    context.checking(new Expectations() {{ 
        oneOf (mockDaoManager).getDao(TblPpvFiltersDao.class);
                               will(returnValue(mockDao));
        oneOf (mockDao).insert(theFilter);
    }});

    PpvFiltersService service = new PpvFiltersServiceImpl(mockDaoManager);

    service.insert(theFilter);
}

导致此错误消息:

java.lang.IllegalStateException: tried to return a $Proxy6 from a method 
    that can only return a com.ibatis.dao.client.Dao

也许我在这里遗漏了一些明显的东西,但上面的代码几乎直接来自 http://www.jmock.org/getting-started.html 的 JMock 示例。

有什么想法吗?

已修复当然这是显而易见的。以上TblPpvFiltersDao需要扩展com.ibatis.dao.client.Dao标记接口。哦。

【问题讨论】:

    标签: java junit ibatis jmock


    【解决方案1】:

    删除对mockDao.proxy() 调用。您希望 getDao() 返回 mockDao 而不是代理。

    另外,您似乎正在使用 JMock 1。我建议您移动具有更好 API 的 JMock(或者甚至移动到协议更简单的Mockito)。在 JMock2 中,您创建一个上下文对象(Mockery 的实例),从中创建模拟对象,它们是您的类的实际实例(而不仅仅是 Mock 类型的实例)。

    Mockery ctx = new Mockery();
    TblPpvFiltersDao dao = ctx.mock(TblPpvFiltersDao.class);
    DaoManager daoManager = ctx.mock(DaoManager.class);
    
    ...
    

    更多详情请见http://www.jmock.org/getting-started.html

    【讨论】:

    • 不,省略 .proxy() 部分我会得到一个 org.jmock.Mock 这不是我想要的。
    • 为什么?如果 mockDaoManager 返回 mockDao,那么您可以测试调用 mockDao.insert() 的期望。这就是测试的重点,不是吗?
    • 这是 JMock 1.2,所以 mockDaoManager 和 mockDao 都是 org.jmock.Mock 的实例。需要 proxy() 调用来获取“真实的”模拟对象。见jmock.org/jmock1-getting-started.html
    • @agnul,我刚刚意识到这一点并添加了几句话。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-16
    • 1970-01-01
    相关资源
    最近更新 更多