6

MockWebServer と Robolectric を使用して、いくつかの API 呼び出しを単体テストしようとしています。

私のテストクラスには次の注釈が付けられています。

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

ただし、Retrofit インスタンスをビルドしようとすると、次の例外が発生します。

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)

改造インスタンスを構築するために使用しているコード:

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

を呼び出すと、上記の例外が返されます.build()

この問題を解決するにはどうすればよいですか?

4

4 に答える 4

6

私はこれと同じ問題を抱えていました。ここで根本的な原因について未解決のバグがありますが、それが進行中の間、Robolectric 3.0 と、以下に含まれるモックを作成するためのここで dave-r12 によって概説されているソリューションを使用することに落ち着きました。

@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;
        }
    }

}
于 2016-06-28T11:42:30.033 に答える
1

うまくいくと思われる別の解決策は、Retrofit をセットアップするときにダミーのエグゼキュータを提供することです。

Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("http://www.example.com/")
            .client(client)
            .callbackExecutor(new Executor() {
                @Override
                public void execute(Runnable command) {
                    //doesn't matter since tests are synchronous
                }
            })
            .addConverterFactory(ScalarsConverterFactory.create())
            .build();

最終的に Retrofit 側で修正する必要があり、現在のプラットフォームが Robolectric であるかどうかを何らかの方法で検出し、ダミーのエグゼキュータなどを返す必要があるかもしれません。

于 2016-09-02T18:53:58.510 に答える
0

sdk=21 で試してみてください。sdk=23 のサポートは、リリース バージョンではなく 3.1-SNAPSHOT からのみ追加されたと思います。

編集:テストを正常に実行できたため、バージョン 3.1 からサポートが追加されました。

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

private MockWebServer mMockServer = new MockWebServer();

    @Test
    public void build_retrofit() throws Exception {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(mMockServer.url(""))
                .addConverterFactory(GsonConverterFactory.create())
                .build();

   }
}

私のgradle.build

testCompile 'junit:junit:4.12'
testCompile "org.robolectric:robolectric:3.1"
testCompile 'com.squareup.okhttp3:mockwebserver:3.3.0'

compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'

どのライブラリのバージョンを使用していますか?

于 2016-06-28T07:09:33.413 に答える