简体   繁体   English

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

[英]Can a JMock mock object return another mock object?

I'm writing tests for an application using the iBatis DAO framework. 我正在使用iBatis DAO框架为应用程序编写测试。 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). 该应用程序在Java 1.4环境中运行,因此我正在使用所有版本的旧版本(JDK 1.4,JUnit3,iBatis 2.3和JMock 1.2)。

In my MockObjectTestCase subclass I have this test 在我的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());        
}

which should verify that the service object will ask the DaoManager for a DAO object and call the insert method on it. 它将验证服务对象将向DaoManager询问DAO对象并在其上调用insert方法。 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 . 尝试将mockDao对象转换为com.ibatis.dao.client.Daocom.ibatis.dao.client.template.SqlMapDaoTemplate都以ClassCastException结尾。

What am I missing? 我想念什么?

Update: nothing changes converting the code to use JDK 1.6, JUnit 4 and JMock2. 更新:将代码转换为使用JDK 1.6,JUnit 4和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 . 也许我在这里缺少明显的东西,但是上面的代码几乎直接来自http://www.jmock.org/getting-started.html上的JMock示例。

Any ideas? 有任何想法吗?

Fixed Of course it was something obvious. 固定当然,这很明显。 TblPpvFiltersDao above needs to extend the com.ibatis.dao.client.Dao marker interface. 上面的TblPpvFiltersDao需要扩展com.ibatis.dao.client.Dao标记接口。 D'oh. 天啊

Remove the .proxy() call on mockDao . 卸下.proxy()的调用mockDao You want getDao() to return mockDao and not a proxy. 您希望getDao()返回mockDao而不是代理。

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). 另外,似乎您正在使用JMock1。我建议您将具有更好API的JMock(甚至移至协议更简单的Mockito )。 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). 在JMock2中,您创建一个上下文对象(Mockery实例),从中创建模拟对象,该对象是类的实际实例(而不仅仅是Mock类型的实例)。

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. 有关更多详细信息,请参见http://www.jmock.org/getting-started.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM