简体   繁体   中英

Can a JMock mock object return another mock object?

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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