2013-07-25 2 views
6

Я - неофит весны, который работает над большим весенним проектом, который имеет обширную связь между весенними бобами. Я пытаюсь написать некоторые интеграционные тесты, которые выполняют подмножества общей функциональности приложения. Для этого я хотел бы переопределить некоторые из них. Например, предположим, что у меня есть классКак переопределить аннотацию Spring @Autowire и задать поле null?

public class MyDataServiceImpl implements MyDataService { 
    @Qualifier("notNeededForMyDataServiceTest") 
    @Autowired 
    private NotNeededForMyDataServiceTest notNeededForMyDataServiceTest; 
    //... 
} 

и контекстный файл:

<bean id="myDataService" 
     class="MyDataServiceImpl"> 
</bean> 

В моем тесте, у меня нет необходимости использовать notNeededForMyDataServiceTest поле. Есть ли способ переопределить аннотацию @Autowired и установить notNeededForMyDataServiceTest в null, возможно, в файле XML? Я не хочу изменять какой-либо из классов Java, но я хочу избежать (проблемной) конфигурации notNeededForMyDataServiceTest.

Я попытался сделать:

<bean id="myDataService" 
     class="MyDataServiceImpl"> 
    <property name="notNeededForMyDataServiceTest"><null/></property> 
</bean> 

Это не работает. IntelliJ сообщает мне: «Невозможно разрешить свойство« notNeededForMyDataServiceTest »», по-видимому, потому, что для этого поля нет геттеров и сеттеров.

Я использую Spring Framework 3.1.3.

+0

Вы пытались: <свойство name = "notNeededForMyTestService" value = "null" />, я думаю, что это даст вам строку null, но вы можете по крайней мере установить значение – Jayz

ответ

5

Следующая конфигурация должна работать, я взял на себя смелость смешивания в конфигурации Java

@Configuration 
//This will load your beans from whichever xml file you are using 
@ImportResource("classpath:/path/beans.xml") 
public class TestConfigLoader{ 
    // This will declare the unused bean and inject MyDataServiceImpl with null. 
    public @Bean(name="notNeededForMyDataServiceTest") NotNeededForMyDataServiceTest getNotNeededForMyDataServiceTest(){ 
     return null; 
    } 
... any other configuration beans if required. 
} 

И аннотировать тестовый класс следующим образом:

// In your test class applicationContext will be loaded from TestConfigLoader 
@ContextConfiguration(classes = {TestConfigLoader.class}) 
public class MyTest { 
    // class body... 
} 
3

Это может помочь:

и профили:

Вы можете создать определение различных компонентов в конфигурации XML, а затем активировать их с помощью -Dspring.profiles.active="profile1,profile2" окр.

+0

приятных ссылок, в точности как требуется – Jayz

+0

Спасибо за указатели! Я даю бонус Эйбу, потому что он представил пример кода. – kc2001

3

Вы используете механизм @Autowired неправильно. Квалификатор не свойство, которое вам нужно установить. На самом деле это имя компонента, так что контейнер сможет выбрать один конкретный экземпляр в случае, если в одном контексте определены несколько компонентов одного и того же типа.

Таким образом, контейнер будет искать фасоль типа NotNeededForMyDataServiceTest и имя (которое на самом деле было бы bean id в XML): notNeededForMyDataServiceTest.

Я думаю, что вы хотите указать, чтобы контейнер не вводил ничего в это поле, если в контексте приложения не определен никакой тип NotNeededForMyDataServiceTest. Это может быть достигнуто лишь путем установки атрибута аннотации required к false:

@Autowired(required = false) 
NotNeededForMyDataServiceTest someOptionalDependency; 

Единственный недостаток этого подхода в том, что контейнер никогда не будет жаловаться во время выполнения, если нет ничего, чтобы ввести в этой области (и, возможно, вам понадобится эта проверка здравомыслия, когда ваш код будет работать).


Если вы не хотите, чтобы сделать эту зависимость по желанию (или вы не можете изменить этот код для какой-либо причины), вам необходимо предоставить макет/null значение для этого поля, установив, что в явном виде в вашем контексте. Один из вариантов заключается в использовании конфигурации Java вместо XML (например, в ответе @ Abe), а другой подход - использовать фабричный компонент, который возвращает null (например, в this question).

+0

Спасибо за ваш ответ. К сожалению, вы правы - нам нужна проверка здравомыслия в производстве. – kc2001

+0

Я отредактировал свой ответ, чтобы предоставить пару альтернатив ... –

+0

Спасибо! Я хотел бы разделить бонус между вашим ответом и Эйбом, но я не могу. Я даю бонус Эйбу, потому что он представил пример кода. – kc2001

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