Повторное использование контекста приложения spring в классах классов 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 для создания проекта.
Ответы
Ответ 1
Да, это вполне возможно. Все, что вам нужно сделать, это использовать те же атрибуты locations
в ваших тестовых классах:
@ContextConfiguration(locations = "classpath:test-context.xml")
Spring кэширует контексты приложений атрибутом locations
, поэтому, если второй раз появляется locations
, Spring использует тот же контекст, а не создает новый.
Я написал статью об этой функции: Ускорение Spring тестов интеграции. Также он подробно описан в документации Spring: 9.3.2.1 Контекстное управление и кэширование.
Это имеет интересную импликацию. Поскольку Spring не знает, когда JUnit завершен, он кэширует весь контекст навсегда и закрывает их с помощью JVM hookdown. Такое поведение (особенно когда у вас много тестовых классов с разными locations
) может привести к чрезмерному использованию памяти, утечкам памяти и т.д. Еще одно преимущество контекста кэширования.
Ответ 2
Чтобы добавить к ответ Tomasz Nurkiewicz, из Spring 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 {
...
}
Используя эту настройку, контекст, который использует "test-db-setup-context.xml", будет создан только один раз, но beans внутри него может быть введен в отдельный контекст unit test
Подробнее о руководстве: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/testing.html#testcontext-ctx-management (поиск " контекстная иерархия" )