2013-05-01 4 views
1

Настройка некоторых интеграционных тестов. У меня возникают проблемы с равенством класса домена. Равенство работает так, как ожидалось, во время нормального выполнения, но при тестировании методов Сервиса с помощью теста интеграции проверка равенства возвращается false.Интеграционный тест Grails - равенство объектов домена

Одна услуги (так называемая в нАлАдкА() СЛУЧАЙ Test) помещает объект домена в сеанс

SomeService { 
    setSessionVehicle(String name) { 
    Vehicle vehicle = Vehicle.findByName(name) 
    session.setAttribute("SessionVehicle", vehicle) 
    } 

    getSessionVehicle() { 
    return session.getAttribute("SessionVehicle") 
    } 
} 

В другом месте в другой службе, я загрузить объект и убедиться, что связанный объект атрибута совпадает с значение сеанса:

OtherService { 
    getEngine(long id) { 
    Vehicle current = session.getAttribute("SessionVehicle") 

    Engine engine = Engine.get(id) 
    if(!engine.vehicle.equals(current)) throw Exception("Blah blah") 
    } 
} 

Это работает, как ожидается, во время нормальной работы, предотвращая загрузку неправильного двигателя (Хорошо, я продезинфицировать имена классов, делать вид, что имеет смысл). Но в тесте интеграции, что .equals() терпит неудачу, когда это удастся:

Vehicle testVehicle 

setUp() { 
    Vehicle v = new Vehicle("Default") 
    v.save() 
    someService.setSessionVehicle("Default") 
    testVehicle = someService.getSessionVehicle() 
} 

testGetEngine() { 
    List<Engine> engines = Engine.findAllByVehicle(testVehicle) 
    //some assertions and checks 
    Engine e = otherService.getEngine(engines.get(0).id) 
} 

findAll() вызова правильно возвращая список всех двигателей, связанных с транспортным средством в сессии, но когда я пытаюсь посмотреть индивидуальный движок по идентификатору, проверка равенства для сеанса Транспортное средство против автомобиля на найденном двигателе не работает. На данный момент создано только одно транспортное средство, и в сообщении об исключении отображается, что сеанс Vehicle и Engine.Vehicle существуют и имеют одно и то же значение.

Если я попытаюсь выполнить проверку равенства в самой тестовой камере, это не сработает, но я могу изменить testCase, чтобы проверить if(vehicle.id == sessionVehicle.id), который преуспевает, но я не заинтересован в изменении моего производственного кода, чтобы удовлетворить интеграцию контрольная работа.

Я делаю что-то неправильно при настройке этих объектов домена в своем тестовом примере, что я должен делать по-другому?

ответ

3

Прежде всего, проверка равенства, которую вы выполняете, - это просто проверка ссылки. Вы не должны использовать метод equals по умолчанию для вашей проверки, лучше переопределите метод equals в классе домена.

Существует два способа переопределить метод equals:
1) вы можете использовать свою IDE для автоматического генерации кода для метода equals (много нулевой проверки и т. Д.).
2) Предпочтительный способ: вы можете использовать классы EqualsBuilder и HashCodeBuilder из проекта Apache Commons. Библиотека должна быть уже доступна для вашего приложения или загружать JAR-файл и размещать в lib.
Вот пример кода для использования EqualsBuilder:

  boolean equals(o) { 
       if (!(o instanceof Vehicle)) { 
        return false 
       } 
       def eb = new EqualsBuilder() 
       eb.append(id, o.id) 
       eb.append(name, o.name) 
       eb.append(otherProperties, o.otherProperties) 
      .... 
       return eb.isEquals() 
      } 

Еще один момент: как вы получаете сеанс в службе? из RequestContextHolder? Хорошей практикой является не доступ к сеансу непосредственно из службы, скорее отправьте значение в качестве параметра метода в службу.

+0

Благодарим вас за ответ, но это вызывает другие вопросы, и, возможно, я все время делал неправильно. 1) У меня создалось впечатление, что переопределение символов 'equals()' и 'hashcode()' было проигнорировано внутри объектов домена grails, так как оно использует свойство 'id' исключительно независимо от того, как вы его определяете в самом домене. 2) Да, я получаю сеанс из RequestContextHolder. Я не уверен, что можно передать переменную каждому методу, если вы не хотите вывести его из сеанса в контроллере, а затем передать его службе? Это переменная, установленная при входе в ** каждый ** метод. – Trebla

+0

1) 'equals()' и 'hashcode()' не игнорируются. если вы сравните все свойство в методе equals, он сделает это, а не только свойство id.Пожалуйста, переопределите оба в своем классе домена, попробуйте тест и дайте нам знать результат. Важное замечание: всегда переопределять hashCode() при переопределении equals(). HashSet и HashMap сначала используют hashCode(), и только call equals() для коллизий. 2) Я хотел получить значение сеанса в контроллере и перейти к сервисному методу в качестве параметра. – Shafiul

+0

Потребовалось некоторое время, прежде чем мое расписание разрешалось, но добавление равных и haschode устраняло эту проблему. Это было мое основное недопонимание объектов домена Грайла. – Trebla

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