2011-12-14 6 views
54

У нас есть куча тестовых примеров JUnit (тесты интеграции), и они логически сгруппированы в разные классы тестов.Повторное использование весеннего контекста приложения в классах тестов junit

Мы можем загрузить контекст приложения Spring раз в тестовый класс и повторно использовать его для всех тестовых случаев в тестовом JUnit классе, как указано в http://static.springsource.org/spring/docs/current/spring-framework-reference/html/testing.html

Однако, мы были просто интересно, если есть способ загрузите контекст приложения Spring только один раз для группы тестовых классов JUnit.

FWIW, мы используем Spring 3.0.5, JUnit 4.5 и используем Maven для создания проекта.

+0

Все ответы на приведенные ниже являются большими, но у меня нет context.xml. Заметил ли я свой путь в Лету? Любой способ сделать это без context.xml? – markthegrea

ответ

67

Да, это вполне возможно. Все, что вам нужно сделать, это использовать один и тот же атрибут locations в тестовых классах:

@ContextConfiguration(locations = "classpath:test-context.xml") 

Spring контекстах кэша приложений с помощью locations атрибута, поэтому если же locations появляется во второй раз, Spring использует тот же контекст, а не создавать новенький.

Я написал статью об этой функции: Speeding up Spring integration tests. Также подробно описано в весенней документации: 9.3.2.1 Context management and caching.

Это имеет интересное значение. Поскольку Spring не знает, когда JUnit завершен, он кэширует весь контекст навсегда и закрывает их с помощью JVM shutdown hook. Такое поведение (особенно когда у вас много тестовых классов с разными locations) может привести к чрезмерному использованию памяти, утечкам памяти и т. Д. Еще одно преимущество контекста кэширования.

+0

Ах! Не понял этого. Мы давно придерживаемся этого подхода, и я (ошибочно) объяснил длительную продолжительность выполнения теста весной загрузкой контекста с каждым тестовым классом. Будем внимательно проверять сейчас. Благодарю. – Ramesh

+0

Я бы сказал, что весна не знает о порядке выполнения ваших тестовых ящиков. В результате этого он не может определить, требуется ли контекст позже или может быть удален. – philnate

+1

Я не вижу, как это может быть правдой. Eclipse/JUnit тратит 2 минуты на запуск среды каждый раз, когда я выполняю тест Run As/JUnit. Это не произойдет, если что-то будет кэшировано. – user1944491

22

Чтобы добавить к Tomasz Nurkiewicz's answer, с весны 3.2.2 @ContextHierarchy аннотация может использоваться для отдельной связанной структуры контекста. Это полезно, когда несколько тестовых классов хотят совместно использовать (например) настройки базы данных в памяти (datasource, EntityManagerFactory, tx manager и т. Д.).

Например:

@ContextHierarchy({ 
    @ContextConfiguration("/test-db-setup-context.xml"), 
    @ContextConfiguration("FirstTest-context.xml") 
}) 
@RunWith(SpringJUnit4ClassRunner.class) 
public class FirstTest { 
... 
} 

@ContextHierarchy({ 
    @ContextConfiguration("/test-db-setup-context.xml"), 
    @ContextConfiguration("SecondTest-context.xml") 
}) 
@RunWith(SpringJUnit4ClassRunner.class) 
public class SecondTest { 
... 
} 

Имея эту установку контекст, который использует «тест-дб-установка-context.xml» будет создан только один раз, но бобы внутри он может быть введен в индивидуальный блок тест-х контекст

Подробнее о руководстве: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/testing.html#testcontext-ctx-management (поиск «context hierarchy»)

+0

У меня многомодульный maven, и я стараюсь избегать настройки базы данных в сервисном модуле (поскольку он уже загружен с помощью тестов модуля данных), и это не работает для меня! –

+2

Это сработало для меня! Благодарю. Чтобы быть ясным, без аннотации @ContextHierarchy весна загружает мой db для каждого теста. Я использую параметр «classes»: @ContextConfiguration (classes = {JpaConfigTest.class, ... – Brel

+4

Любая идея, если это можно сделать полностью через аннотации вместо использования определения XML для контекста? Я много искал это в документе, и здесь, на SO, но не смог найти ничего, что заставило бы меня думать, что это невозможно. –

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