2016-08-19 3 views
8

Раньше я работал в MVP, и я обычно тестировал своих докладчиков, используя простой Junit (Not Instrumentation!), Поскольку докладчики имеют только бизнес-логику и никаких ссылок на внутренние элементы Android вообще.Android plain Junit with Dagger 2

Теперь, переключившись на кинжал 2, я понял, что у меня возникла проблема с настройкой «TestModule» для моего компонента приложения.

  1. Создание компонента не будет работать внутри тестового класса (возможно, потому, что «кв» не работает там)
  2. Не нашли каких-либо примеров для использования Dagger с помощью стандартного тестирования JUnit. Каждый пример, который я нашел, основывается только на контрольно-измерительных тестах или Roboelectric (которые в основном издеваются над действиями и другими предметами, связанными с Android), но для меня это всего лишь тестирование пользовательского интерфейса, и мне это не нужно.

Просто для того, чтобы все было ясно, я говорю о тестах, которые находятся в папке test-> src-> test, а не app-> src-> androidTest!

Так что я делаю что-то неправильно? Или что-то не хватает? Может ли кто-нибудь объяснить или дать примеры того, как использовать Dagger 2 в обычных модульных тестах?

ответ

4

Я не уверен, что мое решение будет работать на вас, но я не вижу причин, почему это не должно. Сначала я создал testInjectionComponent

@Singleton 
@Component(modules = {MockNetworkModule.class}) 
public interface MockInjectionComponent extends InjectionComponent { 
void inject(DaggerUnitTest daggerUnitTest); 
} 

Тогда мои модульных тестов я добавить инъекции в перед тем методом.например:

@Before 
public void setUp() throws Exception { 
    MockInjectionComponent mockInjectionComponent = DaggerMockInjectionComponent 
      .builder() 
      .mockNetworkModule(new MockNetworkModule()) 
      .build(); 
    mockInjectionComponent.inject(this); 
} 

Затем я просто аннотирую свой введенный объект.

EDIT: Не забудьте добавить testApt "com.google.dagger:dagger-compiler:$daggerVersion" в вашем app.gradle файле.

+0

Пробовал уже. Он не компилируется, когда вы пытаетесь вызвать DaggerMockInjectionComponent.builder() ... Он говорит: «... Ошибка: (41, 54) ошибка: не удается найти метод построения знака() ...» Вот ссылка Github: https : //github.com/ivelius/BitcoinGraph/blob/4b9080229f9a2f9c5362b4930bab3dcb979e9e08/app/src/test/java/com/example/yanbraslavski/bitcoingraph/MainPresenterTest.java#L43 – Ivelius

+0

@Ivelius Он должен быть добавлен с кинжалом, поэтому DaggerMockAppComponent затем сделает ваш проект, который Dagger может сгенерировать файл, и он предложит вам импортировать его. –

+0

Да, конечно, была просто опечатка. Я исправил ошибку. он все тот же ... Не компилируется. Вы можете проверить этот небольшой тестовый проект и убедиться сами ... https://github.com/ivelius/BitcoinGraph/blob/DaggerTests/app/src/test/java/com/example/yanbraslavski/bitcoingraph/MainPresenterTest. java – Ivelius

2

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

Например у вас есть этот Presenter:

public class MyPresenter { 

    Database database; 
    ApiService apiService; 

    @Inject 
    public MyPresenter(final Database database, final ApiService apiService) { 
     this.database = database; 
     this.apiService = apiService; 
    } 
} 

Dagger обеспечит ваш Presenter с database и apiService объектов для вашего ведущего, чтобы использовать их. При запуске реального приложения (а не теста) это будут реальные объекты с реальной функциональностью.

При тестировании ведущего вы хотите протестировать только ведущего, все остальное должно быть издевательством.

Поэтому, когда вы создаете презентатора в своем PresenterTest, вы создаете его с издеваемыми версиями database и apiService.

Вы можете проверить, как ваши ведущее взаимодействует с этими объектами с помощью

а. высмеивать поведение объектов, таких как

when(database.getSomething()).thenReturn(something) 

b. проверить ваш ведущий делает то, что вы хотите делать с этими объектами, как

verify(database).saveSomething() 

(псевдо-код)

Стандартный способ поиздеваться бы Mockito.

+0

Спасибо за ваш ответ. Это именно то, что я делаю в настоящее время. Но если я не могу использовать кинжал, чтобы поменять свои модули (настоящий модуль и тестовый модуль), я потеряю одну из основных причин использования DI в моем проекте. Я бы предпочел определить тестовый модуль, который будет иметь эти издеваемые базы данных и объекты apiService, «предоставленные» кинжалом. В этом весь смысл DI! – Ivelius

+2

Если это то, что вы делаете в настоящее время, продолжайте это делать. Else объясните, почему вы считаете, что вам нужен тестовый компонент для ваших модульных тестов и размещать некоторый код :) – FWeigl

+0

Возможно, речь идет не о коде, а о основном понимании DI. Не секрет, что DI упрощает запись тестируемого кода. Проверьте определение DI в википедии. Если мы сами вводим параметры для показа во время теста, мы басически действуем как «инжектор» в шаблоне проектирования DI. Почему бы не использовать рамки для этого? И зачем нам нужны разные модули в кинжале, если они никогда не будут взаимозаменяемы? – Ivelius

0

Вы можете поменять местами реальные модули с помощью поддельных модулей двумя способами: сделать это во время компиляции, используя ароматы, как рекомендовано google architecture samples, или во время выполнения, создав абстрактный метод, который вводит реальную вещь в производственный код и поддельные зависимости в тестовом коде , Во втором случае ваш тест должен подклассифицировать класс, который вы хотите высмеять, и построить компонент из scrach.

+0

Когда я использую Flavors для замены моих модулей, я могу сделать это даже без кинжала. Как показано в примере Google, у них просто разные версии класса Injector, которые действуют как поставщик. В основном они делают DI без кинжала. Вопрос в том, как это сделать с кинжалом? В целом . Если мне нужны обходные пути для выполнения DI с помощью кинжала, зачем мне вообще нужен кинжал? : D – Ivelius

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