一千萬個為什麽

搜索

JMock模擬對象可以返回另一個模擬對象嗎?

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

我錯過了什麽?

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

導致此錯誤消息:

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

也許我在這裏遺漏了一些明顯的東西,但上面的代碼幾乎直接來自 http的JMock示例://www.jmock.org/getting-started.html

有任何想法嗎?

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

最佳答案

刪除 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 細節。

轉載註明原文: JMock模擬對象可以返回另一個模擬對象嗎?