2014-06-20 8 views
8

Próbuję przetestować powiadomienia push z Parse.com za pomocą Robolectric. Ponieważ inicjalizacja musi być wykonana w klasie Application, muszę ją przetestować. Do tej pory aplikacja działa dobrze na emulatorze, ale nie jestem w stanie przetestować jej z Robolectric.Jak przetestować klasę aplikacji w Robolectric?

My onCreate klasy aplikacji:

public void onCreate() { 
      super.onCreate(); 

      // Add your initialization code here 
      Parse.initialize(this, APP_KEY, 
          CLIENT_ID); 

      // Specify an Activity to handle all pushes by default. 
      PushService.setDefaultPushCallback(this, MainActivity.class); 

      // Save the current Installation to Parse. 
      //This is null on test 
      android_id = Secure.getString(getApplicationContext() 
          .getContentResolver(), Secure.ANDROID_ID); 

      System.out.println("android id >>" + android_id); 

      ParseInstallation installation = ParseInstallation 
          .getCurrentInstallation(); 
      installation.put("UniqueId", android_id); 
      installation.saveInBackground(); 

      ParseUser.enableAutomaticUser(); 
      ParseACL defaultACL = new ParseACL(); 

      // If you would like all objects to be private by default, remove this 
      // line. 
      defaultACL.setPublicReadAccess(true); 
      Parse.setLogLevel(Parse.LOG_LEVEL_VERBOSE); 
      ParseACL.setDefaultACL(defaultACL, true); 
    } 

test

@RunWith(RobolectricTestRunner.class) 
public class TestParseApplication extends Application { 
private ParseApplication parseApplication; 

@Before 
public void setup() { 

    parseApplication = new ParseApplication(); 
    parseApplication.android_id = "123"; 

    Robolectric.application = parseApplication; 
} 

@Test 
public void shouldPass() { 
    assertTrue(true); 
} 

} 

StackTrace

WARNING: no system properties value for ro.build.date.utc 
android id >>null 

java.lang.IllegalArgumentException: Must subscribe to channel with a valid icon identifier. 
     at com.parse.PushService.setDefaultPushCallback(PushService.java:298) 
     at com.parse.PushService.setDefaultPushCallback(PushService.java:277) 
     at com.parse.starter.ParseApplication.onCreate(ParseApplication.java:30) 
     at org.robolectric.internal.ParallelUniverse.setUpApplicationState(ParallelUniverse.java:164) 
     at org.robolectric.RobolectricTestRunner.setUpApplicationState(RobolectricTestRunner.java:430) 
     at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:236) 
     at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263) 
     at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68) 
     at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47) 
     at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231) 
     at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60) 
     at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229) 
     at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50) 
     at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222) 
     at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:177) 
     at org.junit.runners.ParentRunner.run(ParentRunner.java:300) 
     at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 
     at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 

Odpowiedz

7

Należy owinąć Parse API do pewnej klasy i wyśmiewać go:

public class ParseAPI { 
    public void init(Context context, String key, String id) { 
     // Add your initialization code here 
     Parse.initialize(context, key, 
         id); 
    } 

    public void initPush(Context context, Class pushCallbackClass) { 
     // Specify an Activity to handle all pushes by default. 
     PushService.setDefaultPushCallback(context, puchCallbackClass); 
    } 
} 

Modyfikuj swoją aplikację:

public void onCreate() { 
    super.onCreate(); 

    ParseAPI api = getParseAPI(); 

    api.init(this, APP_KEY, CLIENT_ID) 
    api.initPush(this, MainActivity.class); 
} 

protected ParseAPI getParseAPI() { 
    return new ParseAPI(); 
} 

zmodyfikować aplikację testową i testy:

@RunWith(RobolectricTestRunner.class) 
public class TestParseApplication extends ParseApplication { 
private ParseApplication parseApplication; 

@Before 
public void setup() { 

    parseApplication = new TestParseApplication(); 
    parseApplication.android_id = "123"; 

    Robolectric.application = parseApplication; 
} 

protected ParseAPI getParseAPI() { 
    return new ParseAPI() { 
       public void init(Context context, String key, String id) { 
       } 

       public void initPush(Context context, Class pushCallbackClass) { 
       } 
    }; 
} 

@Test 
public void shouldPass() { 
    assertTrue(true); 
} 

} 

To powinno działać, jeśli nie zrobić żadnego błędu podczas wpisywania.

Oczywiście, jest to z grubsza. Lepiej jest korzystać z fałszywej biblioteki zamiast pisać anonimowe klasy w testach (Moim ulubionym jest Mockito). Przeczytaj także o inwersji zależności i iniekcji (IoC). I ostatni jest znacznie lepiej oddzielić Robolectric aplikację testową z badań aplikacyjnych (proszę przeczytać http://robolectric.blogspot.nl/2013/04/the-test-lifecycle-in-20.html)

2
public class TestParseApplication extends Application 

powinno to być zestaw testów lub zestaw testowy, a nie rzeczywista klasa testujesz.

Dla każdego testu należy utworzyć instancję klasy Application. Właściwie Robolectric robi to za Ciebie, jeśli prawidłowo zadeklarowałeś klasę aplikacji w swoim manifeście i możesz pobrać bieżącą instancję aplikacji (z ulepszonym zapleczem testowym) z aplikacji robolectric: getShadowApplication().

Powiązane problemy