2014-10-03 5 views
0

Я работаю с Spring 4.0.7 и с JUnit о тестировании, конечно.Попытка генерировать ошибку о введении Spring @Autowired field для JUnit

О DI Spring предлагает @Autowired для использования в трех местах

  • конструктор
  • сеттер
  • поле

Я всегда работаю через два первых, почему никогда третий вариант?

Поскольку я помню, давно прочитал о том, что инъекция в поле не должна использоваться, потому что это имеет отрицательное значение в отношении тестирования. Это делает Юнит.

Примечание: Только для тестирования это проблема. Для времени работы или производства все идет хорошо

Цель: Для демонстрации/академических целей я хочу создать эту проблему.

У меня есть следующая:

Repository

public interface PersonRepository extends JpaRepository<Person, String>{ 

} 

Услуга,

@Service 
@Transactional 
@Profile("failure") 
public class PersonFailTestServiceImpl implements PersonService { 

    private static final Logger logger = ... 

    @Autowired 
    private PersonRepository personRepository; 

Других Услуг (вызов или с помощью службы, указанной выше)

@Service 
@Transactional 
@Profile("failure") 
public class PersonFailTestProcessImpl implements PersonProcess { 

    private static final Logger logger = ... 

    @Autowired 
    private PersonService personService; 

Как у ou может видеть, что две службы основаны на Field Injection.

Теперь тестирование:

Как бобы загружены

@Configuration 
    @ComponentScan(basePackages={"com.manuel.jordan.server.infrastructure"}, 
        basePackageClasses={PersonProcess.class,PersonRepository.class, PersonService.class}) 
    public class CentralConfigurationEntryPoint { 

    } 

    @ContextConfiguration(classes=CentralConfigurationEntryPoint.class) 
    public class CentralTestConfigurationEntryPoint { 
    } 

Теперь два тестирования классов

@Transactional 
@RunWith(SpringJUnit4ClassRunner.class) 
@ActiveProfiles({"development","failure"}) 
public class PersonServiceImplDevelopmentFailureTest extends CentralTestConfigurationEntryPoint { 

    @Autowired 
    private PersonService personService; 

    @Test 
    public void savePerson01(){ 
     Person person01 = PersonFactory.createPerson01(); 
     personService.save(person01); 
     personService.printPerson(personService.findOne("1")); 
    } 

@Transactional 
@RunWith(SpringJUnit4ClassRunner.class) 
@ActiveProfiles({"development","failure"}) 
public class PersonProcessImplDevelopmentFailureTest extends CentralTestConfigurationEntryPoint{ 

    @Autowired 
    private PersonProcess personProcess; 

Ну все методы тестирования проходят, все зеленые. Я не знаю, если я что-то отсутствует или через Spring 4 проблема была исправлена ​​

ответ

1

Я думаю, что смогу помочь. Пример кода, который вы опубликовали здесь, является хорошим примером теста системы/интеграции, а не теста UNIT.

Если вы были методом проверки подлинности PersonFailTestProcessImpl, вам нужно будет самостоятельно установить зависимость personRepository через код. Но это личное, так как вы это делаете? Вы не можете использовать конструктор или сеттер, поскольку он не предоставляется. Это то, что подразумевается под «жестким тестированием».

Java 5+ предоставляет способ установки таких частных переменных, как это посредством отражения (так называемый привилегированный аксессор). В принципе, вы получаете класс, получаете объявленное поле, вызываете его метод setAccessible, тогда вы можете установить его значение напрямую. Существуют библиотеки, которые сделают эти шаги для вас, но дело в том, что это боль по сравнению с X.setSomething();

Таким образом, нет ничего, что «заставляет jUnit fail» использовать @Autowired в частном поле. Но создание объектной модели без конструкторов или сеттеров для установления зависимостей излишне ограничивает.

+0

Спасибо, я вижу проблему, это когда я должен вводить * вручную * зависимость для компонента или компонента, изолированного от других. –

2

Если бы это была ваша посылка или проблема

Потому что я помню, как читал давно о инъекции поле не должно будет использоваться, поскольку он имеет отрицательное значение в отношении Тестирование. Это делает Юнит.

то вы ошибались. Нет ничего по своей сути ошибочным в использовании инъекции в поле, определенно ничего, что могло бы привести к тому, что тесты JUnit не сработают сами по себе. Если существует bean-компонент, Spring сможет его ввести, будь то в конструкторе, методе setter или в поле.

Поскольку вы активировали свой профиль failure, ваш bean-компонент PersonFailTestServiceImpl будет найден.

+0

Я забыл сказать несколько месяцев назад. Я смотрел демо (не записано) о том, как JUnit терпит неудачу, когда '@ Autowired' определен в поле в службе или репозитории и как работает JUnit, когда' @ Autowired' определяется в конструкторе. Кажется, проблема заключается не в том, как «разрешать» bean, а о 'reflection' .. о * read *, был на некоторых сообщениях. –

+0

@ManuelJordan Это, должно быть, был очень конкретный сценарий. –

+0

Да. Конкретный сценарий .... слайд содержит «Даже когда поле является приватным, но трудно выполнить единичный тест». –

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

  • Нет связанных вопросов^_^