2010-04-19 3 views
1

Я пишу тесты для приложения с использованием инфраструктуры iBatis DAO. Приложение работает в среде java 1.4, поэтому я использую устаревшие версии всего (JDK 1.4, JUnit3, iBatis 2.3 и JMock 1.2).Может ли mock-объект 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 объект либо либо com.ibatis.dao.client.Dao или com.ibatis.dao.client.template.SqlMapDaoTemplate концами в ClassCastException.

Что мне не хватает?

Обновление: ничего не изменило, преобразуя код в 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 

может быть, я что-то очевидное здесь отсутствует, но выше код приходит почти прямо из примеров JMock на http://www.jmock.org/getting-started.html.

Любые идеи?

Исправлено: Конечно, это было нечто очевидное. TblPpvFiltersDao выше необходимо расширить интерфейс маркера com.ibatis.dao.client.Dao. D'о.

ответ

0

Удалить .proxy() позвонить по телефону mockDao. Вы хотите, чтобы getDao() возвращал mockDao, а не прокси.

Также кажется, что вы используете JMock 1. Я предлагаю вам переместить JMock, который имеет лучший API (или даже Mockito, чей протокол еще проще). В JMock2 вы создаете объект контекста (экземпляр Mockery), из которого вы создаете mock-объект, который является фактическими экземплярами вашего класса (а не только экземпляром типа Mock).

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

+0

Почему? Если mockDaoManager возвращает mockDao, вы можете проверить, что mockDao.insert() вызывается. Это точка испытания, не так ли? –

+0

Это JMock 1.2, поэтому оба mockDaoManager и mockDao являются экземплярами org.jmock.Mock. Вызов proxy() необходим для получения «реального» макета объекта. См. Http://www.jmock.org/jmock1-getting-started.html – agnul

Смежные вопросы