Может ли макет объекта JMock возвращать другой макет объекта? - PullRequest
1 голос
/ 19 апреля 2010

Я пишу тесты для приложения, использующего инфраструктуру 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.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'о.

1 Ответ

0 голосов
/ 19 апреля 2010

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

Кроме того, похоже, что вы используете JMock 1. Я предлагаю вам переместить JMock, который имеет лучший API (или даже 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.

...