Search code examples
junitretrofitrobolectricmockwebserver

Using MockWebServer with Robolectric


I'm trying to unit test some API calls using MockWebServer and Robolectric.

My test class is annotated with:

@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 23)

However when trying to build the Retrofit instance I get the following exception:

java.lang.NullPointerException
    at android.os.Handler.__constructor__(Handler.java:229)
    at android.os.Handler.<init>(Handler.java)
    at retrofit2.Platform$Android$MainThreadExecutor.<init>(Platform.java:105)
    at retrofit2.Platform$Android.defaultCallbackExecutor(Platform.java:97)
    at retrofit2.Retrofit$Builder.build(Retrofit.java:556)

The code I'm using to build the retrofit instance:

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(mMockServer.url(""))
                .addConverterFactory(GsonConverterFactory.create())
                .build();

The exception above is returned upon calling .build().

How do I fix this problem?


Solution

  • I had this same problem. There is a bug open about the underlying cause here but while that is ongoing, I settled for using Robolectric 3.0 and the solution outlined by dave-r12 here which is to create the mock I've included below.

    @RunWith(RobolectricGradleTestRunner.class)
    @Config(shadows = CreateOkHttpClientTest.MyNetworkSecurityPolicy.class)
    public class CreateOkHttpClientTest {
    
        @Test
        ...
    
        @Implements(NetworkSecurityPolicy.class)
        public static class MyNetworkSecurityPolicy {
    
            @Implementation 
            public static NetworkSecurityPolicy getInstance() {
                try {
                    Class<?> shadow = MyNetworkSecurityPolicy.class.forName("android.security.NetworkSecurityPolicy");
                    return (NetworkSecurityPolicy) shadow.newInstance();
                } catch (Exception e) {
                    throw new AssertionError();
                }
            }
    
            @Implementation 
            public boolean isCleartextTrafficPermitted() {
                return true;
            }
        }
    
    }