2016-09-12 2 views
3

Ich versuche, einige Tests für Fragmente zu schreiben, deren Felder mit @Inject annotiert sind. Zum Beispiel sieht ein Stück meiner app wie folgt aus:Komponententests während der Verwendung von Dolch 2 (Robolectric und Mockito)

Modul:

@Module 
public class PdfFactoryModule { 

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

Komponente:

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

Anwendung:

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

(Beachten Sie, dass diese nur Schnipsel meines ganzen Code sind, ich bin nur das Wesentliche für diese besondere Abhängigkeit klar zu halten, zeigt.)


Ich habe versucht, einen Test wie dies zu tun:

Fake-Modul:

@Module 
public class FakePdfFactoryModule extends PdfFactoryModule { 

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

Fake-Komponente:

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

Fake-Anwendung:

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

Test:

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

Aber die DaggerFakeCorePdfComponent erzeugen nicht. Ich habe viel Zeit verschwendet, weil ich nie mit Abhängigkeitsinjektion getestet habe. Was mache ich falsch?

+0

Wenn Sie mit Dolch im Klassenpfad kompilieren, sollte der Fehler beim Erstellen von DaggerFakeCorePdfComponent mit einem Fehler auf der Registerkarte "Ausgabe" Ihrer IDE oder im Fehlerprotokoll des Compilers angezeigt werden. Kannst du irgendeine Ausgabe so finden? (Separat kann ich nicht sehen, wo Sie Dagger in Ihrem Test verwenden; warum wollen Sie, dass der Test auf die Komponente zugreifbar ist, im Gegensatz zu Ihrem System-Test oder der Abhängigkeit von einer freistehenden Komponente?) –

+0

Es ist einfach sagt 'Fehler: (14, 21) Fehler: kann Symbolvariable nicht finden DaggerFakeCorePdfComponent' Wie für die Tests möchte ich das Fragment selbst testen, aber es wird nicht ohne die Abhängigkeiten laufen. – Haruspik

+0

Ein bisschen von einem Schuss im Dunkeln, aber meine Vermutung ist, dass Robolectric tatsächlich nicht die richtigen Aufgaben zu grillle laufen, um das '' apt''-Plugin und generieren Sie die Klassen für Sie. Hast du versucht '' testCompile '' zusätzlich zu '' apt'' hinzuzufügen?Wenn nicht, kannst du es versuchen und lass es mich hier wissen. – Fred

Antwort

5

Mein Ratschlag - "Dolch nicht in Tests verwenden".

einfach Ihren Code zum nächsten ändern:

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

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

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

Und:

@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

Funktioniert jetzt :) Danke! – Haruspik

1

Sie können versuchen:

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

ich ähnliches Problem hatte, es für mich gearbeitet.

Verwandte Themen