Ответ 1
Вы можете использовать насмешливую инфраструктуру, такую как Mockito, чтобы высмеять все соответствующие классы Hibernate и определить ожидаемое поведение этих макетов.
Звучит как много кода, но поскольку API-интерфейс Hibernate Criteria - это свободный интерфейс, все методы Criteria
возвращают новый экземпляр Criteria
. Таким образом, определение ложного поведения, которое является общим для всех тестов, прост. Вот пример использования Mockito
@Mock
private SessionFactory sessionFactory;
@Mock
Session session;
@Mock
Criteria criteria;
CatDao serviceUnderTest;
@Before
public void before()
{
reset(sessionFactory, session, criteria);
when(sessionFactory.getCurrentSession()).thenReturn(session);
when(session.createCriteria(Cat.class)).thenReturn(criteria);
when(criteria.setFetchMode(anyString(), (FetchMode) anyObject())).thenReturn(criteria);
when(criteria.setFirstResult(anyInt())).thenReturn(criteria);
when(criteria.setMaxResults(anyInt())).thenReturn(criteria);
when(criteria.createAlias(anyString(), anyString())).thenReturn(criteria);
when(criteria.add((Criterion) anyObject())).thenReturn(criteria);
serviceUnderTest = new CatDao(sessionFactory);
}
Все методы " Criteria
возвращаются обратно.
В конкретном тесте вы затем используете ArgumentCaptor
и verify
утверждения, чтобы выяснить, что произошло с издеваемыми Criteria
.
@Test
public void testGetCatByName()
{
ArgumentCaptor<Criterion> captor = ArgumentCaptor.forClass(Criterion.class);
serviceUnderTest.getCatByName("Tom");
// ensure a call to criteria.add and record the argument the method call had
verify(criteria).add(captor.capture());
Criterion criterion = captor.getValue();
Criterion expectation = Restrictions.eq("name", "Tom");
// toString() because two instances seem never two be equal
assertEquals(expectation.toString(), criterion.toString());
}
Проблема, которую я вижу в этом виде унитатов, заключается в том, что они налагают много ожиданий на тестируемый класс. Если вы считаете, что serviceUnderTest
как serviceUnderTest
, вы не можете знать, как он возвращает объект cat по имени. Он также может использовать критерий LIKE
или даже "IN" вместо =
, в дальнейшем он может использовать критерий " Example
. Или он может выполнить собственный SQL-запрос.