Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nullpointerexception when I check for running service in Roboelectric test

I get a NPE when I run a test on an activity whose onCreate() method checks if a particular service is running. In the setup method of the test, I call:

ActivityController<MyActivity> ac = Robolectric.buildActivity(MyActivity.class).create();
    mActivity = ac.get();

In the onCreate() method of the activity, I call isServiceRunning()

ActivityManager manager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
    if(manager != null) {
        for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
            if (service.service != null && "MyService".equals(service.service.getClassName())) {
                return true;
            }
        }
    }
    return false;

It fails with NPE when it executes this:

for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE))

manager is not null, but the NPE is thrown in ActivityManager.getRunningServices(int) in the android library.

What should I do if I need this method to pass? I was using Roboelectric 2.2-20130612.001729-6-jar-with-dependencies.jar but I see the problem now even with the latest version.

I was using android SDK version 19, but I now switched to 18 and I still see the problem.

Any ideas?

Stack trace:

java.lang.NullPointerException  
at android.app.ActivityManager.getRunningServices(ActivityManager.java:1106)
at com.example.MyActivity.isServiceRunning(MyActivity.java:151)
at com.example.MyActivity.onCreate(MyActivity.java:43)
at android.app.Activity.performCreate(Activity.java:5133)
at org.fest.reflect.method.Invoker.invoke(Invoker.java:112)
at org.robolectric.util.ActivityController$1.run(ActivityController.java:116)
at org.robolectric.shadows.ShadowLooper.runPaused(ShadowLooper.java:257)
at org.robolectric.util.ActivityController.create(ActivityController.java:111)
at org.robolectric.util.ActivityController.create(ActivityController.java:123)
at com.example.test.MyActivityTest.setUp(MyActivityTest.java:44)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:233)
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:174)
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)
like image 426
sr09 Avatar asked Feb 27 '14 01:02

sr09


1 Answers

You need to change your if statement to be more inclusive. From the android documentation on the function:
Note: this method is only intended for debugging or implementing service management type user interfaces.

So I would recommend being very careful with your null checkS (note the plural). The order below is important or you might receive the null pointer in the if statement's conditional.

  1. make sure manager is not null and then
  2. make sure the List<> is not null and then
  3. make sure that is not empty.
    (Big difference between null and empty, ex: we cannot run the .isEmpty() function on a null List).

if(manager != null && manager.getRunningServices(MAX) != null && !manager.getRunningServices(MAX).isEmpty() != null)

Side Note: Would be easier to read that after check number 1 you save list of services to a variable and just have a second if statement on that variable and then do your for each statement inside the second if statement.

like image 57
napkinsterror Avatar answered Nov 04 '22 21:11

napkinsterror