В нашем проекте мы просто пишем тест JUnit, который загружает конфигурацию Spring. Это делает несколько вещей, которые вы описали как:
- Проверка XML
- Гарантирует, что bean-компоненты могут быть загружены с классами на пути к классам (по крайней мере bean-компоненты, которые не загружаются ленивым образом)
Он не проверяет, нет ли бобов-сирот. В любом случае, нет надежного способа сделать это, учитывая, что в любом месте вашего кода вы можете искать бины непосредственно по их идентификатору. То, что на bean не ссылаются никакие другие bean-компоненты, не означает, что он не используется. Фактически все конфиги Spring будут иметь хотя бы один bean-компонент, на который не ссылаются другие bean-компоненты, потому что в иерархии всегда должен быть корень.
Если у вас есть bean-компоненты, которые полагаются на real сервисы, такие как базы данных или что-то подобное, и вы не хотите подключаться к этим сервисам в тесте JUnit, вам просто нужно абстрагировать конфигурацию, чтобы учесть значения теста , Это может быть легко выполнено с помощью чего-то вроде PropertyPlaceholderConfigurer , который позволяет вам иметь различные свойства, указанные в отдельных файлах конфигурации для каждой среды, а затем на них ссылается один файл определения bean-компонентов.
РЕДАКТИРОВАТЬ (чтобы включить пример кода):
То, как мы это делаем, это как минимум 3 разных файла пружин ...
- SRC / главная / ресурсы / applicationContext.xml
- SRC / главная / ресурсы / beanDefinitions.xml
- SRC / тест / ресурсы / testContext.xml
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<import resource="classpath:beanDefinitions.xml"/>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="file:path/environment.properties" />
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${driver}" />
...
</bean>
... <!-- more beans which shouldn't be loaded in a test go here -->
</beans>
beanDefinitions.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="myBean" class="com.example.MyClass">
...
</bean>
<bean id="myRepo" class="com.example.MyRepository">
<property name="dataSource" ref="dataSource"/>
...
</bean>
... <!-- more beans which should be loaded in a test -->
</beans>
testContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<import resource="classpath:beanDefinitions.xml"/>
<bean id="dataSource" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="org.springframework.jdbc.datasource.DriverManagerDataSource"/>
</bean>
</beans>
Здесь происходит много вещей, позвольте мне объяснить ...
- Файл applicationContext.xml является основным пружинным файлом для всего приложения. Он содержит bean-компонент PropertyPlaceHolder, позволяющий настраивать определенные значения свойств в различных средах, в которых мы развертываем (тест или продукт). Он импортирует все основные компоненты, необходимые для запуска приложения. Любые bean-компоненты, которые не должны использоваться в тесте, такие как bean-компоненты DB или другие классы, которые взаимодействуют с внешними службами / ресурсами, должны быть определены в этом файле.
- Файл beanDefinitions.xml содержит все ваши обычные компоненты, которые не зависят от внешних факторов. Эти бины могут и будут ссылаться на бины, определенные в файле appContext.xml.
- Файл testContext.xml является тестовой версией appContext. Ему нужны версии всех bean-компонентов, определенных в файле appContext.xml, но мы использовали библиотеку-макет для создания экземпляров этих bean-компонентов. Таким образом, реальные классы не используются и нет риска доступа к внешним ресурсам. Этот файл также не нуждается в бине-заполнителе свойства.
Теперь, когда у нас есть тестовый контекст, который мы не боимся загружать из теста, вот код для этого ...
SpringContextTest.java
пакет com.example;
import org.junit.Test;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class SpringContextTest {
@Test
public void springContextCanLoad() {
XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("testContext.xml"));
for (String beanName : factory.getBeanDefinitionNames()) {
Object bean = factory.getBean(beanName);
// assert anything you want
}
}
}
Это не может быть оптимальным способом сделать это; класс ApplicationContext является рекомендуемым способом загрузки контекстов пружины. Вышеприведенное может быть заменено на:
@Test
public void springContextCanLoad() {
ApplicationContext context = new FileSystemXmlApplicationContext("classpath:testContext.xml");
}
Я считаю, что одна строка выполнит все, что вам нужно, чтобы убедиться, что ваш весенний контекст правильно подключен. Оттуда вы можете загружать бины и утверждать, как раньше.
Надеюсь, это поможет!