2016-09-12 6 views
3

Я пытаюсь написать несколько тестов для фрагментов, которые имеют поля, аннотированные с помощью @Inject. Например, кусок моего приложения выглядит следующим образом:Тестирование модуля при использовании кинжала 2 (Robolectric and Mockito)

Модуль:

@Module 
public class PdfFactoryModule { 

    @Provides @Singleton 
    PdfFactory providePdfFactory() { 
     return PdfFactory.getPdfFactory(); 
    } 
} 

Компонент:

@Singleton 
@Component(modules = PdfFactoryModule.class) 
public interface CorePdfComponent { 
    void inject(PagerFragment pagerFragment); 
} 

Применение:

public class CorePdfApplication extends Application { 
    @NonNull 
    private CorePdfComponent component; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     component = DaggerCorePdfComponent.builder().build(); 
    } 

    @NonNull 
    public CorePdfComponent getComponent() { 
     return component; 
    } 

} 

PagerFragment:

public class PagerFragment extends Fragment { 
@Inject PdfFactory pdfFactory; 

@Override 
public void onCreate(@Nullable Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    //Dagger 2 
    ((CorePdfApplication) getActivity().getApplication()).getComponent().inject(this); 
} 

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


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

Поддельный Модуль:

@Module 
public class FakePdfFactoryModule extends PdfFactoryModule { 

    @Override 
    PdfFactory providePdfFactory() { 
     return Mockito.mock(PdfFactory.class); 
    } 
} 

Поддельный компонент:

@Singleton 
@Component(modules = FakePdfFactoryModule.class) 
public interface FakeCorePdfComponent extends CorePdfComponent { 
    void inject(PagerFragmentTest pagerFragmentTest); 
} 

Поддельный Применение:

public class FakeCorePdfApplication extends CorePdfApplication { 
    @NonNull 
    private FakeCorePdfComponent component; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     component = DaggerFakeCorePdfComponent.builder().build(); 
    } 

    @NonNull 
    public FakeCorePdfComponent getComponent() { 
     return component; 
    } 
} 

Тест:

@RunWith(RobolectricTestRunner.class) 
@Config(constants = BuildConfig.class, sdk = 21, application = FakeCorePdfApplication.class) 
public class PagerFragmentTest { 

    PagerFragment pagerFragment; 

    @Before 
    public void setup() { 
     pagerFragment = new PagerFragment(); 
     startVisibleFragment(pagerFragment); 
    } 

    @Test 
    public void exists() throws Exception { 
     assertNotNull(pagerFragment); 
    } 

Но DaggerFakeCorePdfComponent не генерирует. Я, возможно, перепутал большое время, потому что я никогда не тестировал инъекцию зависимости. Что я делаю не так?

+0

Если вы компилируете с помощью кинжала в пути к классам, то при сбое создания DaggerFakeCorePdfComponent должна появиться ошибка на вкладке «Выход» IDE или в журнале ошибок вашего компилятора. Можете ли вы найти такой вывод? (Отдельно, я не вижу, где вы используете Dagger в своем тесте, почему вы хотите, чтобы тест был доступен на Компоненте, в отличие от получения вашего системного теста или зависимости от автономного компонента?) –

+0

Это просто говорит 'Ошибка: (14, 21) ошибка: не удается найти символьную переменную DaggerFakeCorePdfComponent' Что касается тестов, я хотел бы протестировать сам фрагмент, но он не будет работать без зависимостей. – Haruspik

+0

Немного выстрела в темноте, но я предполагаю, что robolectric на самом деле не выполняет правильные задачи градиента, чтобы запустить плагин '' apt'' и генерировать классы для вас. Вы пытались добавить '' testCompile '' в дополнение к '' apt''?Если нет, вы можете дать ему выстрел и сообщить мне здесь PLS. – Fred

ответ

5

Мой совет - «Не используйте кинжал в тестах».

Просто измените код на следующий:

public class FakeCorePdfApplication extends CorePdfApplication { 
    @NonNull 
    private CorePdfComponent component = mock(CorePdfComponent.class); 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
    } 

    @NonNull 
    public CorePdfComponent getComponent() { 
     return component; 
    } 
} 

И:

@RunWith(RobolectricTestRunner.class) 
@Config(constants = BuildConfig.class, sdk = 21, application = FakeCorePdfApplication.class) 
public class PagerFragmentTest { 

    PagerFragment pagerFragment; 

    @Before 
    public void setup() { 
     pagerFragment = new PagerFragment(); 
     CorePdfComponent component = ((CorePdfApplication)RuntimeEnvironment.application).getComponent(); 

     doAnswer(new Answer() { 
      Object answer(InvocationOnMock invocation) { 
      fragment. pdfFactory = mock(PdfFactory.class); 
      return null; 
      } 
     }).when(component).inject(pageFragment); 
     startVisibleFragment(pagerFragment); 
    } 

    @Test 
    public void exists() throws Exception { 
     assertNotNull(pagerFragment); 
    } 
} 
+0

Работает сейчас :) Спасибо! – Haruspik

1

Вы можете попробовать:

androidTestApt "com.google.dagger:dagger-compiler:<version>" 

У меня была аналогичная проблема, он работал на меня.