使用Dagger 2(Robolectric和Mockito)进行单元测试

时间:2016-09-12 17:13:11

标签: android unit-testing mockito robolectric dagger-2

我正在尝试为带有@Inject注释字段的片段编写一些测试。例如,我的应用程序的一大块看起来像这样:

模块:

@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没有生成。我可能搞砸了很长时间,因为我从未测试过依赖注入。我做错了什么?

2 个答案:

答案 0 :(得分:7)

我的建议 - "不要在测试中使用匕首"。

只需将您的代码更改为下一个:

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);
    }
}

答案 1 :(得分:1)

您可以尝试:

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

我遇到了类似的问题,它对我有用。