16

Added LeakCanary (1.3) to my Application:

@Override
public void onCreate() {
    super.onCreate();
    Fabric.with(this, new Crashlytics());
    LeakCanary.install(this);

When I run the Robolectric test suite for my application I get a NullPointerException in LeakCanary.

Caused by: java.lang.NullPointerException
at com.squareup.leakcanary.LeakCanary.isInServiceProcess(LeakCanary.java:165)
at com.squareup.leakcanary.LeakCanary.isInAnalyzerProcess(LeakCanary.java:141)
at com.squareup.leakcanary.LeakCanary.install(LeakCanary.java:52)
at com.squareup.leakcanary.LeakCanary.install(LeakCanary.java:43)
at com.package.application.MyApplication.onCreate(MyApplication.java:50)
at org.robolectric.internal.ParallelUniverse.setUpApplicationState(ParallelUniverse.java:131)
at org.robolectric.RobolectricTestRunner.setUpApplicationState(RobolectricTestRunner.java:431)
at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:224)

I added that Im using Crashlytics to point out that it (and other methods as well) receives the same Application but does not throw any Exceptions.

Wasn't sure if this should be here or on GitHub issues for LeakCanary. Anyone else experiencing this issue?

erafn
  • 191
  • 7
  • 1
    Have a look at the sourcecode of LeakCanary.java, Seems like the HeapAnalyzerService is not running when executing the tests. – WenChao May 11 '15 at 23:43
  • 2
    Override your application in tests and suppress Crashlitics and LeakCanary initialisation. More information here (http://robolectric.org/custom-test-runner/) – Eugen Martynov May 12 '15 at 05:10
  • Thanks! I went with the custom application class option. – erafn May 12 '15 at 07:53

2 Answers2

15

Converting my comment to the answer.

Robolectric provides way to deal with different initialisations and application test lifecycles through test application.

Here is your application class:

public class <YourAppplication> extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Fabric.with(this, new Crashlytics());
        LeakCanary.install(this);
    }
}

You should put in test sources in the same package as yours application next class:

public class Test<YourAppplication> extends <YourApplication> {
    @Override
    public void onCreate() {
    }
}

Robolectric will load it instead of your application. As you can see I suppress all static initialisations from your application.

You can find more details here

Eugen Martynov
  • 19,888
  • 10
  • 61
  • 114
0

A simple way to avoid the NullPointerException is to disable LeakCanary for unit tests by specifying the release (no-op) version in the testCompile directive in build.gradle. For instance:

dependencies {
    ...
    testCompile (
        'junit:junit:4.12',
        'org.robolectric:robolectric:3.0',
        'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1'
    )
    ...
}
stevehs17
  • 1,466
  • 2
  • 14
  • 19