0

Mock ich habe eine LoginActivity, die eine SplashFragment in onResume() lädt.Wie man ein benutzerdefiniertes ImageView für Aktivität Unit Test

Das Layout-XML des Splash-Fragments enthält eine benutzerdefinierte ImageView namens RotatingImageView, die, wie der Name schon sagt, ein Quellbild zu rotieren beginnt, sobald es an das Fenster angehängt ist.

Jetzt verursacht dies Probleme, wenn ich versuche, einen Komponententest für LoginActivity unter Verwendung ActivityInstrumentationTestCase2<LoginActivity> zu schreiben. Ich versuche, die Tests auf einem echten Gerät (unrooted), nicht einem Emulator auszuführen.

Der Aufruf getActivity() startet die Aktivität, aber wegen der rotierenden Bildansicht (die eine Animation btw ist), ist der Espresso fest. Ich weiß, dass es Espresso nicht mag, dass dort eine Animation läuft. Ich Ausnahmen erhalten, dass

„Espresso nicht Absicht innerhalb von 45 Sekunden starten könnte. Vielleicht ist der Haupt Thread innerhalb einer angemessenen Zeit nicht untätig geblieben? Es könnte eine Animation oder etwas ständig den Bildschirm neu zu streichen. Oder die Aktivität erstellt Netzwerkaufrufe beim Erstellen Siehe die Thread-Dump Protokolle.Zu Ihrer Referenz der letzte Mal die Ereigniswarteschlange im Leerlauf war Ihre Aktivität Startanforderung war 1487296262885 und jetzt das letzte Mal die Warteschlange im Leerlauf war: 1487296262885 Wenn diese Nummern gleich sind, könnte Ihre Aktivität die Ereigniswarteschlange manipulieren ... "

Jetzt offensichtlich ist das Problem irgendwie/stoppen Sie die Animation verspotten.

  1. Ich habe bereits alle Animationsoptionen aus dem Gerät deaktiviert -> Einstellungen -> Optionen Entwickler aber noch, wenn die Aktivität gestartet wird Ich sehe das Bild Spinne so bedeutet dies nicht helfen.

  2. Ich habe auch in Disable animations for Espresso tests aussehen, aber das hat mir viel auch nicht geholfen. Ich hätte es falsch machen können, aber es hilft sowieso nicht.

  3. Eine andere Option ist das Starten von LoginActivity mit einer speziellen Absicht, die der Aktivität mitteilt, dass diese unter Test gestartet wird. Wenn Sie also das Fragment laden, wird die Animation deaktiviert. Diese Methode funktioniert, ist aber nicht ideal, da Code in der Hauptklasse hinzugefügt wird, die nur zum Testen dient.

Eine andere Lösung könnte sein, RotatingImageView zu verspotten und in SplashFragment zu injizieren, bevor es Laden beginnt. Ich hätte den Anruf zu startSpinningAnimation verspottet, also, wenn es in das Fenster geladen wird, startet es die Animation nicht.

Meine Frage ist: Ist es möglich? Kann ich diese benutzerdefinierte imageView in mein Fragment irgendwie vortäuschen und injizieren, bevor der Anruf zu getActivity() erfolgt?

Antwort

1

Ja, es ist möglich, Sie können eine Klasse namens AnimationUtil erstellen, legen Sie Ihre Animationsmethoden in diese Klasse und mock sie während des Tests.

public Animation getWhateverAnimation(int duration){ 
    RotateAnimation anim = new RotateAnimation(0f, 350f, 15f, 15f); 
    anim.setInterpolator(new LinearInterpolator()); 
    anim.setRepeatCount(Animation.INFINITE); 
    anim.setDuration(duration); 
    return anim; 
} 

und erstellen Sie ein MockAnimationUtil dass extendAnimationUtil in Ihrem androidTest Paket (nicht main Paket) und und Verfahren außer Kraft setzen.

public Animation getWhateverAnimation(int duration){ 
    return super.getWhateverAnimation(0); 
} 
+0

Danke. Das funktioniert. Ich nahm die Animationslogik in eine separate Klasse von der 'CustomImageView'. Das Fragment würde eine Instanz von MyApplication erhalten. In den Tests kann ich eine Scheininstanz in die 'MyApplication'-Instanz injizieren, bevor die Testaktivität gestartet wird. Funktioniert! – kdas