Поделитесь контейнером spring между тестовым приложением и встроенным котом

Мы используем огурец-jvm для написания слоя интеграционного теста в нашем приложении. Одна из проблем, с которыми мы столкнулись, — это управление базой данных между тестами и веб-приложением.

Типичный сценарий заключается в том, что мы хотим сохранить некоторые объекты на заданном этапе сценария, а затем выполнить некоторые действия в пользовательском интерфейсе, которые, в свою очередь, могут сохранить больше объектов. В конце мы хотим очистить базу данных. Поскольку тесты огурца-jvm находятся в одной jvm, а веб-приложение работает в другой jvm, мы не можем разделить транзакцию (по крайней мере, так, как я знаю), поэтому базу данных необходимо очищать вручную.

Моя первоначальная мысль состояла в том, чтобы использовать встроенный сервер Tomcat, работающий от встроенной базы данных в памяти (HSQLDB) в той же JVM, что и в тесте Cucumber-JVM. Таким образом, мы могли бы совместно использовать один контейнер Spring и, соответственно, одну транзакцию, из которой можно было бы получить все объекты.

Во время моих первоначальных тестов кажется, что Spring загружается и настраивается дважды: один раз, когда запускается тест и читается огурец.xml, и второй раз, когда запускается встроенный кот и веб-приложение читает свой applicationContext.xml. Кажется, что они находятся в двух совершенно разных контейнерах, потому что, если я попытаюсь разрешить объект в одном контейнере, который указан в другом контейнере, он не разрешится. Если я дублирую свою конфигурацию, я получаю ошибки о дублирующихся bean-компонентах с тем же идентификатором.

Есть ли способ сказать Spring использовать один и тот же контейнер как для моего тестового приложения, так и для встроенного кота?

Я использую Spring 3.2.2.GA и Embedded Tomcat 7.0.39 (последние версии обеих библиотек).

Я сумасшедший? Нужно ли мне предоставлять больше технических деталей? Извините, если я использую неправильную терминологию.

Спасибо

p.s. Если моя проблема покажется вам знакомой и вы можете предложить альтернативное решение по сравнению с тем, которое я пытаюсь решить, дайте мне знать!


person Jeffrey Cameron    schedule 11.04.2013    source источник


Ответы (2)


Джефф,

Это нормально, что пружина нагружена дважды. Есть два места, где создаются два пружинных контекста:

  1. В прослушивателе контейнера сервлета org.springframework.web.context.ContextLoaderListener, настроенном в web.xml. Этот считывает свою конфигурацию из файла, заданного контекстным параметром contextConfigLocation.
  2. В реализации ObjectFactory предоставляется плагин огурца-спринга огурца.runtime.java.spring.SpringFactory. Этот считывает свою конфигурацию из огурца.xml.

Два контекста spring совершенно разные, и их экземпляры хранятся в двух разных местах. В качестве атрибута контекста сервлета для первого и сохраненного JavaBackend для второго.

При запуске встроенного кота можно получить доступ к контексту сервлета и, таким образом, установить контекст весны, используемый bt tomcat, с контекстом из огурца. Но у Spring есть специальный класс WebApplicationContext для контекста, используемого в контейнере сервлета. Огурец SpringFactory, с другой стороны, создает свой контекст через ClassPathXmlApplicationContext. Поэтому, если нет способа указать тип контекста приложения из конфигурации xml, нам придется предоставить ObjectFactory, который запускает WebApplicationContext.

person Thierry    schedule 13.04.2013
comment
Я нашел ответ, который приближается к тому, что нам нужно. Вы можете установить родительский контекст для WebApplicationContext, это может быть ClassPathXmlApplicationContext. См. этот ответ: stackoverflow.com/questions/14608373/ - person Jeffrey Cameron; 13.04.2013
comment
Еще один дополнительный вопрос: если бы мы могли использовать родительский контекст огурца-спринга в веб-приложении, то мы хотели бы определить все наши службы, источники данных, транзакции и т. д. в огурце.xml для тестов, но определить их из web.xml при обычном запуске сервера. Как мы могли это сделать? - person Jeffrey Cameron; 13.04.2013

Что мы можем сделать, так это иметь два файла web.xml. Один для нормального и один для теста. Для теста мы используем нашу версию слушателя ContexLoader.

person Thierry    schedule 14.04.2013
comment
Я на шаг впереди тебя. См. этот вопрос stackoverflow.com/q/15988578/61344 - person Jeffrey Cameron; 14.04.2013
comment
Но что, если мы решим проблему с web.xml на уровне сборки? Вместо загрузки tomcat из src/webapp мы можем использовать target/webapp, в котором скопирован правильный файл web.xml. - person Thierry; 15.04.2013
comment
Это интересная идея! Хотя сегодня у меня все заработало. Я только что программно настроил файл web.xml. Я могу показать вам завтра. Не должно быть слишком сложно взять упакованное решение из песочницы и применить его к основной кодовой базе. - person Jeffrey Cameron; 15.04.2013