2012-10-24 23 views
12

Mam następujący Aktywny:Testowanie onActivityResult()

package codeguru.startactivityforresult; 

import android.app.Activity; 
import android.content.Intent; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.Button; 
import android.widget.Toast; 

public class StartActivityForResult extends Activity { 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     this.startButton = (Button) this.findViewById(R.id.start_button); 
     this.startButton.setOnClickListener(onStart); 
    } 

    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
     int result = data.getIntExtra(StartActivityForResult.this.getString(R.string.result), -1); 
     String msg = "requestCode=" + requestCode + ", resultCode=" + resultCode + ", result=" + result; 
     Toast.makeText(this, msg, Toast.LENGTH_LONG).show(); 
    } 

    private View.OnClickListener onStart = new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      Intent intent = new Intent(StartActivityForResult.this, ChildActivity.class); 

      StartActivityForResult.this.startActivityForResult(intent, R.id.child_request); 
     } 
    }; 
    private Button startButton = null; 
} 

a następujący test JUnit:

package codeguru.startactivityforresult; 

import android.app.Activity; 
import android.app.Instrumentation; 
import android.test.ActivityInstrumentationTestCase2; 
import android.test.UiThreadTest; 
import android.widget.Button; 
import junit.framework.Assert; 

public class StartActivityForResultTest extends ActivityInstrumentationTestCase2<StartActivityForResult> { 

    public StartActivityForResultTest() { 
     super(StartActivityForResult.class); 
    } 

    @Override 
    public void setUp() throws Exception { 
     super.setUp(); 

     this.setActivityInitialTouchMode(false); 

     this.activity = this.getActivity(); 
     this.startButton = (Button) this.activity.findViewById(R.id.start_button); 
    } 

    @Override 
    public void tearDown() throws Exception { 
     this.activity.finish(); 

     super.tearDown(); 
    } 

    @UiThreadTest 
    public void testStartButtonOnClick() { 
     Assert.assertTrue(this.startButton.performClick()); 

     Instrumentation.ActivityResult result = new Instrumentation.ActivityResult(Activity.RESULT_OK, null); 
     Assert.assertNotNull(result); 

     Instrumentation.ActivityMonitor am = new Instrumentation.ActivityMonitor(ChildActivity.class.getName(), result, true); 
     Assert.assertNotNull(am); 

     Activity childActivity = this.getInstrumentation().waitForMonitorWithTimeout(am, TIME_OUT); 
     Assert.assertNotNull(childActivity); 

     Assert.fail("How do I check that StartActivityForResult correctly handles the returned result?"); 
    } 
    private Activity activity = null; 
    private Button startButton = null; 
    private static final int TIME_OUT = 5 * 1000; // 5 seconds 
} 

Jak widać, ja zorientowali się, jak makiety wynik używając Instrumentation.ActivityResult i Instrumentation.ActivityMonitor. Jak mogę sprawdzić, czy ten wynik jest poprawny?

+0

Brak linku z pytaniem, ale nie ma potrzeby pisania 'Assert.assert * (...)', ponieważ 'ActivityInstrumentationTestCase2' rozszerza' junit.framework.Assert': 'assert * (...)' to Metoda instancji może być wywołana bezpośrednio. – Vince

+1

@Vince Tak, jestem tego świadomy. Osobiście preferuję to szczególne użycie, ponieważ wszystkie metody "assert *()" są statyczne. –

Odpowiedz

1

Stosować zamiary ramy drwić wynik działalności

intending(hasComponent(DummyActivity.class.getName())).respondWith(new ActivityResult(resultCode, dataIntent)); 
rule.getActivity().startActivityForResult(new Intent(context,DummyActivity.class)); 

zweryfikować wynik na działalności logiki

-2
+0

Jak widać z mojego kodu, wiem, jak używać 'onActivityResult()' w moim działaniu 'StartActivityForResult'. Moje pytanie brzmi: jak napisać test JUnit, aby upewnić się, że zachowuje się poprawnie. –

9

Do testowania onActivityResult() w klasie testowej, wszystko co musisz zrobić, to:

  1. Załóż ActivityMonitor który łapie tworzenie ChildActivity i przestrajania makiety ActivityResult.
  2. Symulacja kliknięcia przycisku uruchamia funkcję ChildActivity dla wyniku.
  3. Dokonaj pewnej oceny stanu i próbnego działania ActivityResult. StartActivityForResult

Próbka: StartActivityForResultTest

public class StartActivityForResult extends Activity { 
    private boolean activityResultIsReturned = false; 
    private String activityResult = null; 

    ... ... 

    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    activityResultIsReturned = true; 
    activityResult = data.getStringExtra("result"); 

    ... ... 
    } 

    ... ... 
} 

Próbka:

public class StartActivityForResultTest extends ActivityInstrumentationTestCase2<StartActivityForResult> { 
    ... ... 

    public void testOnActivityResult() { 
    // Get current Activity and check initial status: 
    StartActivityForResult myActivity = getActivity(); 
    assertFalse(myActivity.getActivityResultIsReturned()); 
    assertNull(myActivity.getActiityResult()); 

    // Mock up an ActivityResult: 
    Intent returnIntent = new Intent(); 
    returnIntent.putExtra("result", "This is the result"); 
    Instrumentation.ActivityResult activityResult = new Instrumentation.ActivityResult(Activity.RESULT_OK, returnIntent); 

    // Create an ActivityMonitor that catch ChildActivity and return mock ActivityResult: 
    Instrumentation.ActivityMonitor activityMonitor = getInstrumentation().addMonitor(ChildActivity.class.getName(), activityResult , true); 

    // Simulate a button click that start ChildActivity for result: 
    final Button button = (Button) myActivity.findViewById(com.company.R.id.open_next_activity); 
    myActivity.runOnUiThread(new Runnable() { 
     @Override 
     public void run() { 
     // click button and open next activity. 
     button.performClick(); 
     } 
    }); 

    // Wait for the ActivityMonitor to be hit, Instrumentation will then return the mock ActivityResult: 
    ChildActivity childActivity = getInstrumentation().waitForMonitorWithTimeout(activityMonitor, 5); 

    // How do I check that StartActivityForResult correctly handles the returned result? 
    assertTrue(myActivity.getActivityResultIsReturned()); 
    assertEqual(myActivity.getActiityResult(), "This is the result"); 
    } 

    ... ... 
} 
+0

Dzięki za sugestie. Moja klasa StartActivityForResult w oryginalnym wpisie jest po prostu przykładem. W mojej prawdziwej aplikacji mam do tuzina różnych działań do przetestowania. Niektóre z tych działań zwracają więcej niż jedną część danych. Twój kod testowy sugeruje, że muszę zmodyfikować interfejs każdego działania tylko do testowania przez dodanie modułów pobierających dla każdego fragmentu danych zwróconego przez działanie podrzędne. Nie mam nic przeciwko dodatkowej pracy pisania tego kodu. Nie jestem całkowicie zadowolony z zanieczyszczania kodu produkcyjnego kodem używanym tylko do testowania. –

+0

To są tylko próbki pokazujące, jak przetestować onActivityResult() i zrobić kilka podstawowych twierdzeń, zależą od twojego zapotrzebowania, nie musisz zmieniać swojej klasy aktywności we wszystkich przypadkach, na przykład, jeśli cała twoja funkcja onActivityResult() nie aktualizuje niektórych Pliki interfejsu użytkownika, tj. TextView, można bezpośrednio sprawdzić zaktualizowany tekst bez dodawania żadnych zmiennych instancji i metod getter/setter. – yorkw

+0

To dobra uwaga. Wyobrażam sobie, że w większości przypadków 'onActivityResult()' zmodyfikuje interfejs użytkownika w pewien sposób, jak powiedziałeś. –

Powiązane problemy