Макет JPA CriteriaBuilder с Mockito - PullRequest
       53

Макет JPA CriteriaBuilder с Mockito

3 голосов
/ 08 февраля 2012

У меня есть особенно неприятный блок JMock Checking () для запроса JPA, который Я хочу перенести в Mockito :

Mockery jMock = new Mockery();
final EntityManager fakeEntityManager = jMock.mock(EntityManager.class);
final CriteriaBuilder fakeCriteriaBuilder = jMock.mock(CriteriaBuilder.class);
final CriteriaQuery<String> fakeCriteriaQuery = jMock.mock(CriteriaQuery.class);
jMock.checking(new Expectations() {{
    oneOf(fakeEntityManager).getCriteriaBuilder(); will(returnValue(fakeCriteriaBuilder));
    oneOf(fakeCriteriaBuilder).createQuery(String.class); will(returnValue(fakeCriteriaQuery));
    oneOf(fakeCriteriaQuery).from(Archiveusergrouplicences.class);
    oneOf(fakeCriteriaQuery).select(with(any(Selection.class)));
    oneOf(fakeCriteriaBuilder).isNotNull(with(any(Expression.class)));
    oneOf(fakeCriteriaQuery).where(with(any(Expression.class)));
    oneOf(fakeEntityManager).createQuery(fakeCriteriaQuery);
    // Return an empty resultset
}});

Тестируемый код выглядит следующим образом:

CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<String> criteria = builder.createQuery(String.class);

Root<Archiveusergrouplicences> institution = criteria.from(Archiveusergrouplicences.class);
criteria.select(institution.get(Archiveusergrouplicences_.usergroupid));    
criteria.where(builder.isNotNull(institution.get(Archiveusergrouplicences_.usergroupid)));

List<String> result = entityManager.createQuery(criteria).getResultList();

Я нашел этот вопрос о строителях насмешек , который каким-то образом решает часть макета CriteriaBuilder;но моя главная проблема заключается в использовании макетов объектов в качестве значения .thenReturn () другого макета - похоже, что Mockito этого не допускает.Например, для строки:

CriteriaQuery<String> criteria = builder.createQuery(String.class);

Я хочу вернуть фиктивный объект CriteriaQuery, например:

CriteriaQuery<String> fakeCriteriaQuery = mock(CriteriaQuery.class, RETURNS_DEEP_STUBS);
when(entityManager.createQuery(anyString())).thenReturn(fakeCriteriaQuery);

Это приводит к синтаксической ошибке:

Метод thenReturn (Query) в типе OngoingStubbing не применим к аргументам (CriteriaQuery)

Как можно протестировать этот код или улучшить его, чтобы сделать его более тестируемым?

Ответы [ 2 ]

2 голосов
/ 08 февраля 2012

Оказывается, вы можете возвращать макеты из других макетов - при условии, что вы установите правильные аргументы!Я пытался утверждать:

when(entityManager.createQuery(anyString())).thenReturn(fakeCriteriaQuery);

Когда то, что я на самом деле хотел, было передать в классе:

when(fakeCriteriaBuilder.createQuery(String.class)).thenReturn(fakeCriteriaQuery);

Ошибка была в загадочном способе Мокито сказать, что я облажалсяожидание.

Однако я могу переписать этот тест, а не переводить то, что было написано изначально.Как некоторые из них указали;часто таким способом лучше избегать насмешливых библиотек, а проверяемое условие довольно расплывчато.

0 голосов
/ 08 февраля 2012

Как и вы jMock CriteriaQuery

final CriteriaQuery<String> fakeCriteriaQuery = jMock.mock(CriteriaQuery.class);

Вам также нужно смоделировать CriteriaQuery

final CriteriaQuery<String> fakeCriteriaQuery = mock(CriteriaQuery.class);
...