2016-03-20 3 views
1

Недавно я начал изучать весну и концепцию инъекции зависимостей. У меня есть некоторые сведения о Junit тестирование и Монофонические концепты, но до сих пор не смогли обернуть мою голову вокруг конкретного преимущества, связанного с тестированием, которое предлагает инъекция зависимостей.Испытательное преимущество при инъекции зависимостей

Например я создаю экземпляр класса Triangle следующим образом: -

Triangle triangle1 = new Triangle(); 

и теперь инъекции зависимостей с помощью Spring, я делаю это следующим образом

Triangle triangle2 = (Triangle) beanFactory.getBean("triangle"); 

Произнесите Triangle класс имеет некоторые методы которые нуждаются в тестировании. Какими будут разные подходы в тестировании triangle1 и triangle2

+1

Используйте инъекцию конструктора вместо инъекции в поле. Тогда вы все равно можете использовать 'new' в своих модульных тестах, предоставляя mocks для зависимостей. – chrylis

+0

И даже если вы собираетесь использовать 'getBean' (1. используйте инъекцию конструктора, 2. autowire в свой тестовый класс), используйте общую подпись. – chrylis

ответ

1

С весной вы явно не просматриваете фасоль с завода. Вместо этого контейнер инициализирует компоненты, прежде чем вы их используете, поэтому ваш код не должен вызывать сам контейнер.

В веб-приложении принято использовать веб-контроллеры, которые обрабатывают преобразование веб-запросов и сообщений в вызовы бизнес-логике, услуги, которые обрабатывают транзакцию бизнес-логики, и объекты доступа к данным с помощью методов, каждый из которых выполняет простой запрос или обновление. (Все они обычно являются безстоящими, единственными членами экземпляра являются ссылки на другие объекты без гражданства, и они могут одновременно выполнять несколько запросов.) Объекты на каждом уровне зависят от объектов на следующем нижнем уровне, а Spring соединяет все эти объекты при запуске ,

Если у меня есть контроллер, который использует сервис, Spring создает контроллер и службу и прокладывает службу в контроллер. Код приложения никогда не вызывает фабрику компонентов.

public class SomeWebController { 
    private MyBusinessLogicService myBusinessLogicService; 

    public SomeWebController(MyBusinessLogicService myBusinessLogicService) { 
     this.myBusinessLogicService = myBusinessLogicService; 
    } 
    ... 
} 

Единичный тест не обязательно должен знать о контейнере. Тест может настроить тестируемый объект, подключая к ним свои зависимости, либо путем создания этих зависимостей, либо путем вызова методов setter напрямую, либо путем создания тестовой конфигурации, и с этим подключением к mocks.

Если у меня есть контроллер, который не использует Spring, и он запускает службу непосредственно с помощью своего конструктора, тогда сложнее заменить макет для службы. Я должен был бы сделать что-то вроде рефакторинга, чтобы ввести фабричный метод для службы, а в тесте переопределить его, чтобы вернуть макет. Это приведет к заключению кода шаблона в те тесты, где мне пришлось подклассифицировать класс, который я тестировал, и у меня были бы пробелы в моем охвате, где переопределенные заводские методы не выполнялись.

+0

Спасибо за ответ. Поэтому, когда я тестирую второй случай в своем оригинальном посте, я бы написал примерно следующее: 'Triangle tester = Mockito.mock (Triangle.class);' Не могу написать то же самое для своего первого случая? Каким образом агностик в контейнере ставит меня в выгодную ситуацию? – user3559089

+0

@ user3559089; более примерный пример поможет. Spring - для соединения вещей вместе, когда у вас есть только один объект, в качестве примера трудно понять, в чем проблема. –

+0

Можете ли вы дать мне пример из флеши? Я не знаю, какой пример вы думаете ... Спасибо! – user3559089

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