2014-06-20 13 views
8

Sto provando a testare la notifica push con Parse.com utilizzando Robolectric. Poiché l'inizializzazione deve essere eseguita in una classe di applicazione, ho bisogno di testarlo. Finora l'app funziona perfettamente con l'emulatore, ma non sono in grado di testarlo con Robolectric.Come testare la classe dell'applicazione con Robolectric?

mio onCreate di classe di applicazione:

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

prova

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

risposta

7

Si dovrebbe avvolgere Parse API per qualche classe e mock:

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

modifica l'app:

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

modifica l'app di test e test:

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

} 

Questo dovrebbe funzionare se non faccio alcun errore durante la digitazione.

Ovviamente questa è un'idea approssimativa. È meglio utilizzare alcune librerie fittizie invece di scrivere classi anonime nei test (il mio preferito è Mockito). Si prega di leggere anche l'inversione di dipendenza e l'iniezione (IoC). E per ultimo è molto meglio separare applicazione di test Robolectric da test applicativi (si prega di leggere http://robolectric.blogspot.nl/2013/04/the-test-lifecycle-in-20.html)

2
public class TestParseApplication extends Application 

Questo dovrebbe essere un insieme di test o di una suite di test, non la classe reale che si sta testando.

Per ciascun test, è necessario creare un'istanza della classe Application. In realtà, Robolectric lo fa per te se hai dichiarato correttamente la classe Application nel tuo manifest, e puoi ottenere l'istanza dell'applicazione corrente (con funzionalità di testing avanzate) da aup robolectric: getShadowApplication().

Problemi correlati