Issue
Is it possible to unit test GCM upstream messaging with the help of robolectric? This is my unit:
public void sendUpstream(Bundle data)
{
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
String id = "trv2" + System.currentTimeMillis();
try {
gcm.send(GCM_SENDER_ID + "@gcm.googleapis.com", id, data);
} catch (IOException e) {
printStackTrace(e);
}
}
Trying to test it with robolectric produces the following stacktrace:
java.lang.NullPointerException
at com.google.android.gms.gcm.GoogleCloudMessaging.zza(Unknown Source)
at com.google.android.gms.gcm.GoogleCloudMessaging.send(Unknown Source)
at com.google.android.gms.gcm.GoogleCloudMessaging.send(Unknown Source)
This seems to tell me that instead of using a shadow class robolectric is directly trying to use the GoogleCloudMessaging
class and failing because the test is not being executed on a device.
I tried creating a shadow GoogleCloudMessaging class to see if that would work. THis is the shadow:
@Implements(GoogleCloudMessaging.class)
public class ShadowGCM {
Bundle data;
String to;
String msgId;
public ShadowGCM() {}
@Implementation
public void send(String to, String msgId, Bundle data) {
this.data = data;
this.to = to;
this.msgId = msgId;
}
}
The following anotations were added to my test class to make it work.
@RunWith(MyTestRunner.class)
@Config(manifest = "src/main/AndroidManifest.xml", shadows = {ShadowGCM.class } ,
constants = BuildConfig.class, sdk = Build.VERSION_CODES.KITKAT)
The MyTestRunner was a custom test runner that I created because just putting the 'shadows' attribute into the config annotation doesn't seem to work. Here is the test runner.
public class MyTestRunner extends RobolectricGradleTestRunner {
public MyTestRunner(Class<?> klass) throws InitializationError {
super(klass);
}
@Override
public InstrumentationConfiguration createClassLoaderConfig() {
InstrumentationConfiguration.Builder builder = InstrumentationConfiguration.newBuilder();
builder.addInstrumentedClass(ShadowGCM.class.getName());
builder.addInstrumentedClass(ShadowInstanceID.class.getName());
return builder.build();
}
}
But after all this work. the NullPointerException
is still there. Roboelectric does not look like it's using my shadow class.
Solution
Small mistake ... the line builder.addInstrumentedClass( .. );
specify a class which could be shadowed. Instead of the ShadowGCM use the GoogleCloudMessaging at this point.
The part manifest = "src/main/AndroidManifest.xml"
may give you trouble later. Instead you should take the manifest from build directory which is already done by RobolectricGradleTestRunner. If you have issues in AndroidStudio then read "Note for Linux and Mac Users" at http://robolectric.org/getting-started/
Answered By - nenick
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.