2010-04-19 95 views
1

我正在爲使用iBatis DAO框架的應用程序編寫測試。該應用程序運行在Java 1.4環境中,因此我使用的是舊版本(JDK 1.4,JUnit3,iBatis 2.3和JMock 1.2)。JMock模擬對象可以返回另一個模擬對象嗎?

在我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對象投要麼在ClassCastExceptioncom.ibatis.dao.client.Daocom.ibatis.dao.client.template.SqlMapDaoTemplate末端。

我錯過了什麼?

更新:沒有什麼更改將代碼轉換爲使用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標記接口。 D'哦。

回答

0

刪除.proxy()致電mockDao。您希望getDao()返回mockDao而不是代理。

此外,似乎你正在使用JMock 1.我建議你移動具有更好的API(甚至協議更簡單的Mockito)JMock。在JMock2中,創建一個上下文對象(Mockery的實例),從中創建模擬對象,它們是您類的實際實例(而不僅僅是模擬類型的實例)。

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

... 

有關更多詳細信息,請參見http://www.jmock.org/getting-started.html

+0

不,忽略.proxy()部分我會得到一個org.jmock.Mock,這不是我想要的。 – agnul 2010-04-19 14:46:06

+0

爲什麼?如果mockDaoManager返回mockDao,則可以測試調用mockDao.insert()的期望值。這是測試的重點,不是嗎? – 2010-04-19 15:10:25

+0

這是JMock 1.2,所以mockDaoManager和mockDao都是org.jmock.Mock的實例。 proxy()調用需要獲得「真正的」模擬對象。見http://www.jmock.org/jmock1-getting-started.html – agnul 2010-04-19 15:16:50