JMock 模拟对象可以返回另一个模拟对象吗?

发布于 2024-08-29 09:26:31 字数 2353 浏览 4 评论 0原文

我正在使用 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

有什么想法吗?

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

I'm writing tests for an application using the iBatis DAO framework. The app is running in a java 1.4 environment, so I'm using legacy versions of everything (JDK 1.4, JUnit3, iBatis 2.3 and JMock 1.2).

In my MockObjectTestCase subclass I have this test

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());        
}

which should verify that the service object will ask the DaoManager for a DAO object and call the insert method on it. The test fails with the error message

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

Trying to cast the mockDao object either to either com.ibatis.dao.client.Dao or com.ibatis.dao.client.template.SqlMapDaoTemplate ends in a ClassCastException.

What am I missing?

Update: nothing changes converting the code to use JDK 1.6, JUnit 4 and JMock2. This code

@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);
}

results in this error message:

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

maybe I'm missing something obvious here, but the code above comes almost straight from the JMock examples at http://www.jmock.org/getting-started.html.

Any ideas?

Fixed Of course it was something obvious. TblPpvFiltersDao above needs to extend the com.ibatis.dao.client.Dao marker interface. D'oh.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

尤怨 2024-09-05 09:26:31

删除 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细节。

Remove the .proxy() call on mockDao. You want getDao() to return mockDao and not a proxy.

Also, it seems that you are using JMock 1. I suggest that you to move JMock which has a better API (or even to Mockito whose protocol is even simpler). In JMock2, you create a context object (instance of Mockery) from which you create mock object which are actual instances of your class (and not just instance of the Mock type).

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

...

See http://www.jmock.org/getting-started.html for more details.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文