7

Wie Sie die Referenz der Aktivität abrufen, bevor ihr onCreate aufgerufen wird. während es im Test ist. Ich benutze ActivityTestRule als JUnit Regel. Der Grund für diese Anforderung ist, dass ich Mocks aus Tests in die Aktivität injizieren möchte.So erhalten Sie die Aktivitätsreferenz, bevor ihr OnCreate während des Tests aufgerufen wird

public class MyActivity extends Activity{ 

    MyComponent myComponent; 

    @Override 
    public void onCreate(Bundle savedInstanceState){ 
     super.onCreate(savedInstanceState); 
     if(myComponent==null){ 
      myComponent ... //initialise dagger component 
     } 
     myComponent.inject(this); 
     ... 
    } 

    public void setComponent(MyComponent comp){ 
     this.myComponent = comp; 
    } 
} 

public class MyTest{ 

    @Rule 
    public ActivityTestRule<MyActivity> intentsTestRule = new ActivityTestRule<>(MyActivity.class); 


    MyComponent myFakeComponent; 

    @Before          
    public void setUp() {       
     MyActivity activity = intentsTestRule.getActivity(); 
     activity.setComponent(myFakeComponent); 
    }            

    @Test 
    public void testMethod1(){...} 
} 
+0

Haben Sie 'Dagger' verwenden?Wenn ja, wo initiieren Sie die Module von Dagger? – eleven

+0

Ich mache es in Setup() –

Antwort

0

Ist dieser Code vollständig? Ich kann dich nicht beim Erstellen des Dolchgraphen sehen. Wie auch immer, was ich in meinem Code mache, ist eine statische Klasse namens Injector, die das Diagramm für mich erstellt und auch Elemente in Objekte einfügen kann. In meiner Anwendungsklasse rufe ich sie also auf, um das Diagramm zu erstellen, und alle anderen Aktivitäten verwenden nur das vorhandene Diagramm.

Dann könnten Sie in einem Test eine falsche Testanwendungsklasse erstellen, die das Diagramm auf eine andere Weise initialisiert, oder einfach das Diagramm neu erstellen, das die Injector-Methoden aufruft, bevor die Aktivität erstellt wird. Ich bin mit ActivityTestRule nicht vertraut, daher kann ich mit dem Lebenszyklus dieses Tests nicht viel anfangen.

Aber stellen Sie sicher, dass Sie ein neues Diagramm erstellen, bevor die Aktivität erstellt wird, und lassen Sie die Aktivität nur das vorhandene Diagramm verwenden. Wie die Aktivität auf das Diagramm zugreifen? Nun, ich mag es nicht wirklich, aber wir sind es gewohnt, auf die Anwendungsklasse zuzugreifen (mit explizitem Cast) und sie zu bitten, die Abhängigkeiten für uns einzufügen. So machen es Dagger-Beispiele auch.

14

Laut der Dokumentation, was Sie hier tun, ist falsch.

@Rule 
public ActivityTestRule<MyActivity> intentsTestRule = new ActivityTestRule<>(MyActivity.class); 

MyComponent myFakeComponent; 

@Before          
public void setUp() {       
    MyActivity activity = intentsTestRule.getActivity(); 
    activity.setComponent(myFakeComponent); 
}    

Denn

Diese Regel stellt die Funktionsprüfung eines einzelnen Aktivität. Die zu testende Aktivität wird vor jedem Test gestartet, der mit Test und vor mit @Before annotierten Methoden kommentiert wurde. Es wird beendet, nachdem der Test abgeschlossen ist und die Methoden kommentiert mit After sind abgeschlossen. Während der Testdauer können Sie Ihre Aktivität direkt bearbeiten.

Jedoch!

protected void beforeActivityLaunched() 

überschreibt diese Methode beliebigen Code auszuführen, die vor Ihrer Aktivität erstellt ausgeführt werden sollen und ins Leben gerufen. Diese Methode wird vor jeder Testmethode aufgerufen, einschließlich einer mit @Before annotierten Methode.

Deshalb, wenn Sie die Initialisierung der MainActivityComponent außerhalb der Aktivität an einen Ort verschieben, die mockable ist, dann werden Sie in der Lage sein, es zusammen zu basteln, bevor die Haupttätigkeit erstellt wird.

EDIT:

Eine andere mögliche Lösung ist es, die Aktivität als pro link zu träge einzuleiten.

@Rule 
public ActivityTestRule<NoteDetailActivity> mNoteDetailActivityTestRule = 
     new ActivityTestRule<>(NoteDetailActivity.class, true /* Initial touch mode */, 
       false /* Lazily launch activity */); 

@Before 
public void intentWithStubbedNoteId() { 
    // Add a note stub to the fake service api layer. 
    FakeNotesServiceApiImpl.addNotes(NOTE); 

    // Lazily start the Activity from the ActivityTestRule this time to inject the start Intent 
    Intent startIntent = new Intent(); 
    startIntent.putExtra(NoteDetailActivity.EXTRA_NOTE_ID, NOTE.getId()); 
    mNoteDetailActivityTestRule.launchActivity(startIntent); 

    registerIdlingResource(); 
} 
0

Hier ist mein Beispielcode für das:

public class TestClass { 

    @Rule 
    public ActivityTestRule<T> activityRule = new ActivityTestRule<T>(type) { 
      @Override 
      protected void beforeActivityLaunched() { 
       //TODO inject mocks, setup stubs etc.. 
      } 
     }; 
    } 

    @Before 
    public void before() { 
     activityRule.getActivity(); 
    } 

    @Test 
    public void myTest() { 
     //... 
    } 


} 
Verwandte Themen