Модульный / интеграционный тест дао, состоящий из универсальных методов - PullRequest
1 голос
/ 21 февраля 2012

Вот примеры методов:

public <T> T save(final T o){
  return (T) sessionFactory.getCurrentSession().save(o);
}

public <T> T get(final Class<T> type, final Long id){
  return (T) sessionFactory.getCurrentSession().get(type, id);
}

public <T> List<T> getFieldLike(final Class<T> type, final String propertyName,
            final String value, final MatchMode matchMode)  {
    final Session session = sessionFactory.getCurrentSession();
    final Criteria crit = session.createCriteria(type);
    crit.add(Restrictions.like(propertyName, value, matchMode));
    return crit.list();
}

Есть ли какие-нибудь советы по тестированию модуля или интеграции?Проходить в пробном сеансе?

Ответы [ 3 ]

1 голос
/ 21 февраля 2012

Единственное, что вы можете сделать в модульном тесте, это смоделировать Session и Criteria и установить ожидания - я сделал это в нескольких случаях, используя JMock, и в итоге мне пришлось написать совпадение Hamcrest для Restricitons. Я не уверен, что в этом есть какая-то ценность, кроме слепого увеличения покрытия тестами.

С другой стороны - написание здесь интеграционного теста будет иметь определенное применение, создайте базу данных в памяти с некоторыми данными и подтвердите, что методы возвращают правильные объекты

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

По вашему вопросу я предполагаю, что вы сами управляете своими сессиями. Я буду говорить о модульном тестировании. Интеграционные тесты могут быть выполнены в базе данных в памяти во время интеграции. Насколько я знаю, H2 или Derby - одни из самых популярных.

Вы можете пойти, передав ложную сессию своему DAO, но что произойдет, если один из ваших коллег напишет юнит-тест и забудет пройти пробную сессию? Вы попали в базу данных? Если вы НЕ хотите использовать базу данных, такой подход может стать проблемой

Что может быть лучше, если использовать абстрактный шаблон фабрики даже для получения Дао. В основном ваш код в настоящее время выглядит так:

MyDao.get(someId);

Однако вы можете пойти следующим образом:

Если вы сначала определите свой Дао так:

public interface IDao <SomeGenerics> {
   public <T> T get(Class<T> type, ID key);
   //more generic methods
}

Тогда у вас может быть реализация Дао, которая выглядит так:

public class MyDao <SomeGenerics> implements IDao<SomeGenerics> {
    public <T> T get(Class<T> type, ID key){
        //some real session stuff
    }
    //...more real session stuff
}

Затем в своих модульных тестах вы можете определить макет вашего интерфейса IDao, например:

public class MyDaoMock <SomeGenerics> implements IDao<SomeGenerics> {
    //this thingy can hold a small array of mock instances
    private ArrayList<T> mockInstances;

    public <T> T get(Class<T> type, ID key){
        //some fake stuff, kinda like this;
        for (T mockInstance : mockInstances) {
               if ( mockInstance.getId().equals(key) ) {//here i assume your T has a method getId, you figure out the kinks
                     return mockInstance;
               }
        }
        //if not found, emulate your persistence's behavior, return null, throw an exception or do whatever
        return null;

    }
    //...more fake stuff
} 

Теперь у вас есть интерфейс и две реализации, одна для вашего рабочего кода и одна для ваших модульных тестов. Теперь все, что вам нужно сделать, это реализовать шаблон фабрики, чтобы дать вам правильный дао в производстве и в тестировании кода.

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

Пример интеграционного теста для get ():

// if you can inject the object:
// @Inject 
// public MyTestDAO<MyType> dao;
// 

@Test
public testGet() throws Exception {
    Session session = HibernateUtils.getSessionFactory().getCurrentSession();
    MyTestDAO<MyType> dao = new MyTestDAO<MyType>();
    // if you use DI facility, check against null
    // assertNotNull(dao)
    MyType myType = dao.get(Test.class, 1L);
    assertNotNull(myType);
    assertEqual(myType, equalObj);
    // more asserts? 
}

Если вы используете Spring Framework, вы можете использовать модуль Spring-Test для использования DI с использованием контекста Spring и класса Runner:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring.xml"})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...