13

I've been running tests with Robolectric and it's all been great. Then I implemented Google Analytics to my application class and the tests started failing. The failing seems to occur when I inflate views during tests. Here's the stack trace:

java.lang.NullPointerException: null
at com.google.analytics.tracking.android.AnalyticsGmsCoreClient$AnalyticsServiceConnection.onServiceConnected(AnalyticsGmsCoreClient.java:176)
at org.robolectric.shadows.ShadowApplication$2.run(ShadowApplication.java:209)
at org.robolectric.util.Scheduler$PostedRunnable.run(Scheduler.java:162)
at org.robolectric.util.Scheduler.runOneTask(Scheduler.java:107)
at org.robolectric.util.Scheduler.advanceTo(Scheduler.java:92)
at org.robolectric.util.Scheduler.advanceToLastPostedRunnable(Scheduler.java:68)
at org.robolectric.util.Scheduler.unPause(Scheduler.java:25)
at org.robolectric.shadows.ShadowLooper.unPause(ShadowLooper.java:219)
at org.robolectric.shadows.ShadowLooper.runPaused(ShadowLooper.java:258)
at org.robolectric.shadows.ShadowViewGroup.addView(ShadowViewGroup.java:32)
at android.view.ViewGroup.addView(ViewGroup.java)
at android.view.ViewGroup.addView(ViewGroup.java:3225)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:750)
at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
at org.robolectric.shadows.ShadowView.inflate(ShadowView.java:82)
at android.view.View.inflate(View.java)

Here's the Robolectric code for my BaseActivity:

@RunWith(RobolectricTestRunner.class)
public class BaseActivityTest {

ActivityController<TestActivity> activityController;
TestActivity activity;

@Before
public void setUp(){
    activityController = Robolectric.buildActivity(TestActivity.class).create().start();
}


@After
public void takeDown(){
    activityController.stop().destroy();
    activity = null;
}

@Test
public void testOnPauseState(){
    activity = activityController.resume().pause().get();
    assertFalse(activity.getBus().isActive());
}
}

Following the Google Analytics example, my Application class implements Google Analytics. Whenever I run the tests with my Application, the break occurs. I've tried implementing Robolectric's MockApplication object, but that had no change; I had to remove Google Analytics from my Application object to have it work. Does anyone have any solutions that would allow me to run Robolectric with Google Analytics?

Maxwell
  • 6,532
  • 4
  • 37
  • 55

3 Answers3

19

There is another solution if the previous posts don't work. Get a handle to the shadow application and configure it to ignore the analytics start intent binding. Do this in your test setup.

@Before
public void setup() {
    ShadowApplication shadowApplication = Robolectric.shadowOf(Robolectric.application);
    shadowApplication.declareActionUnbindable("com.google.android.gms.analytics.service.START");
}
George Papas
  • 503
  • 3
  • 9
3

I have two suggestions for you if you are using Google Analytics V3:

1) Have you tried calling this method when you run your tests?

 googleAnalytics.setAppOptOut(true); 

This will disable google analytics for the lifetime of the test.

2) Create a test application class in the same package as your current application and name it the same name but prepend "Test" to the name. This application will be created during your tests and you can set "setAppOptOut" set to true or you can omit GoogleAnalytics altogether from it.

More information can be found here: http://robolectric.blogspot.com/2013/04/the-test-lifecycle-in-20.html

Marco RS
  • 8,145
  • 3
  • 37
  • 45
  • 1
    The second option worked. One important thing to remember that's explained in the link is that the application classes must be in the same package (along with having the same name with "Test" prepended to the test application class). The first option, albeit makes sense, doesn't seem to register during tests. – Maxwell Nov 04 '13 at 17:50
  • The first option does not work for me due to that it fails at `GoogleAnalytics.getInstance(this)` therefore it never reaches the line containing `setAppOptOut(true)` – Kevin Crain Aug 03 '15 at 13:13
2

I tried all the above solutions and none of them worked for me. This finally did:

public class TestFooApplication extends FooApplication {
    @Override
    public boolean bindService(Intent service, ServiceConnection conn, int flags) {
        return false;
    }
}
gleenn
  • 628
  • 6
  • 17