0

私はEspresso UIテストを開始しました。私はカスタムMockTestRunnerMockApplicationを初期化用に用意しています。Daggerコンポーネントとモックモジュールも定義しました。それは以下のようになります。テストの実行に失敗しました: 'android.os.NetworkOnMainThreadException'のために計測が失敗しました

public class MockTestRunner extends AndroidJUnitRunner { 
    public Application newApplication(ClassLoader cl, String className, Context context) 
      throws InstantiationException, IllegalAccessException, ClassNotFoundException { 
     return super.newApplication(cl, MockMyApplication.class.getName(), context); 
    } } 

MyAppが、私はgradle

defaultConfig { 
     .... 
     multiDexEnabled true 

     testInstrumentationRunner "a.b.c.MockTestRunner" 
    } 

testInstrumentationRunnerを追加

public class MockQrApplication extends MyApp { 
    private MockWebServer mockWebServer; 

    protected void initComponent() { 
     mockWebServer = new MockWebServer(); 

     component = DaggerMyAppComponent 
       .builder() 
       .myAppModule(new MyAppModule(this)) 
       .busModule(new BusModule()) 
       .apiModule(new MockApiModule(mockWebServer)) 
       .facebookModule(new FacebookModule()) 
       .dataManagerModule(new DataManagerModule()) 
       .greenDaoModule(new GreenDaoModule()) 
       .trackModule(new TrackModule(this)) 
       .build(); 

     component.inject(this); 
    } 
} 

によって拡張されて、私は私のLoginActivity

@RunWith(AndroidJUnit4.class) 
@LargeTest 
public class LoginActivityTest { 
    protected Solo solo; 

    @Rule 
    public ActivityTestRule<LoginActivity> activityTestRule = new ActivityTestRule(LoginActivity.class); 

    @Before 
    public void setUp() throws Exception { 
     initVariables(); 
    } 

    protected void initVariables() { 
     solo = new Solo(InstrumentationRegistry.getInstrumentation(), activityTestRule.getActivity()); 
    } 

    @Test 
    public void testLayout() { 
     solo.waitForFragmentByTag(LoginFragment.TAG, 1000); 

     onView(withId(R.id.email_input)).perform(clearText(), typeText("[email protected]")); 
     onView(withId(R.id.pass_input)).perform(clearText(), typeText("qqqqqqqq")); 
     onView(withId(R.id.login_button)).perform(click()); 

     solo.waitForDialogToOpen(); 
    } 
} 
にログインテストを実行したいです

私は私のテストを実行したい場合は、私が得た:

Client not ready yet.. 
Started running tests 
Test running failed: Instrumentation run failed due to 'android.os.NetworkOnMainThreadException' 
Empty test suite. 

[編集]

これはApiModuleクラス

public class MockApiModule extends ApiModule { 
    private MockWebServer mockWebServer; 

    public MockApiModule(MockWebServer mockWebServer) { 
     this.mockWebServer = mockWebServer; 
    } 

    @Override 
    public OkHttpClient provideOkHttpClient(DataManager dataManager) { 
     return new OkHttpClient.Builder() 
       .build(); 
    } 

    @Override 
    public Retrofit provideRetrofit(OkHttpClient okHttpClient) { 
     Retrofit retrofit = new Retrofit.Builder() 
       .baseUrl(mockWebServer.url("/"))  // throw NetworkOnMainThreadException 
       .addConverterFactory(NullOnEmptyConverterFactory.create()) 
       .addConverterFactory(GsonConverterFactory.create(new Gson())) 
       .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) 
       .client(okHttpClient) 
       .build(); 
     return retrofit; 
    } 

    @Override 
    public ApiService provideApiService(Retrofit retrofit) { 
     return retrofit.create(ApiService.class); 
    } 

    @Override 
    public ApiClient provideApiManager(Application application, ApiService apiService, DataManager dataManager) { 
     return new MockApiClient(application, apiService, dataManager, mockWebServer); 
    } 
} 

APIログイン要求がそのように見える拡張MockApiModuleです:

apiService.postLoginUser(userLoginModel).enqueue(new Callback<JsonObject>() { 
      @Override 
      public void onResponse(Call<JsonObject> call, Response<JsonObject> response) { 
       if (response.isSuccess()) { 
        LoginResponse loginResponse = null; 
        try { 
         loginResponse = gson.fromJson(MockResponse.getResourceAsString(this, "login.json"), LoginResponse.class); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 
        callback.onLoginSuccess(loginResponse); 
       } else { 
        callback.onLoginFail(response.errorBody().toString()); 
       } 
      } 

      @Override 
      public void onFailure(Call<JsonObject> call, Throwable t) { 
       callback.onLoginFail(t.getMessage()); 
      } 
     }); 

変更すると機能します私はstracktrace

android.os.NetworkOnMainThreadException 
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1285) 
at java.net.InetAddress.lookupHostByName(InetAddress.java:431) 
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252) 
at java.net.InetAddress.getByName(InetAddress.java:305) 
at okhttp3.mockwebserver.MockWebServer.start(MockWebServer.java:303) 
at okhttp3.mockwebserver.MockWebServer.start(MockWebServer.java:293) 
at okhttp3.mockwebserver.MockWebServer.maybeStart(MockWebServer.java:143) 
at okhttp3.mockwebserver.MockWebServer.getHostName(MockWebServer.java:172) 
at okhttp3.mockwebserver.MockWebServer.url(MockWebServer.java:198) 
at com.mooduplabs.qrcontacts.modules.MockApiModule.provideRetrofit(MockApiModule.java:38) 
at com.mooduplabs.qrcontacts.modules.ApiModule_ProvideRetrofitFactory.get(ApiModule_ProvideRetrofitFactory.java:23) 
at com.mooduplabs.qrcontacts.modules.ApiModule_ProvideRetrofitFactory.get(ApiModule_ProvideRetrofitFactory.java:9) 
at dagger.internal.ScopedProvider.get(ScopedProvider.java:46) 
at com.mooduplabs.qrcontacts.modules.ApiModule_ProvideApiServiceFactory.get(ApiModule_ProvideApiServiceFactory.java:23) 
at com.mooduplabs.qrcontacts.modules.ApiModule_ProvideApiServiceFactory.get(ApiModule_ProvideApiServiceFactory.java:9) 
at dagger.internal.ScopedProvider.get(ScopedProvider.java:46) 
at com.mooduplabs.qrcontacts.modules.ApiModule_ProvideApiManagerFactory.get(ApiModule_ProvideApiManagerFactory.java:31) 
at com.mooduplabs.qrcontacts.modules.ApiModule_ProvideApiManagerFactory.get(ApiModule_ProvideApiManagerFactory.java:11) 
at dagger.internal.ScopedProvider.get(ScopedProvider.java:46) 
at com.mooduplabs.qrcontacts.activities.BaseActivity_MembersInjector.injectMembers(BaseActivity_MembersInjector.java:44) 
at com.mooduplabs.qrcontacts.activities.BaseActivity_MembersInjector.injectMembers(BaseActivity_MembersInjector.java:13) 
at com.mooduplabs.qrcontacts.components.DaggerQrContactsAppComponent.inject(DaggerQrContactsAppComponent.java:91) 
at com.mooduplabs.qrcontacts.activities.BaseActivity.init(BaseActivity.java:74) 
at com.mooduplabs.qrcontacts.activities.BaseActivity.onCreate(BaseActivity.java:64) 
at android.app.Activity.performCreate(Activity.java:6367) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1110) 
at android.support.test.runner.MonitoringInstrumentation.callActivityOnCreate(MonitoringInstrumentation.java:532) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2404) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2511) 
at android.app.ActivityThread.access$900(ActivityThread.java:165) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1375) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:150) 
at android.app.ActivityThread.main(ActivityThread.java:5621) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:684) 
+2

エラーメッセージはかなり明確です。あなたはUIスレッド内でネットワークコールを行っています。インストゥルメントテストではUI(メイン)スレッドがあり、その動作は実際のデバイスでアプリケーションを起動したときと同じです。ネットワークコールを含む可能性のあるコードを表示してください –

+0

あなたの答えはちょっと、Thy、私は 'MockApiModule'とログインリクエストを追加しました。私はエラーメッセージを理解していますが、理由はわかりません。テストが開始できず、そのメッセージが表示されるので、 – Michael

+0

テストスレッド内でAPIログインメソッドを使用することはできません。この関数はsetUp()メソッドの間にどこかで呼び出されますか? –

答えて

0

を取得MockTestRunner

におけるアプリケーションのMyAppクラスにはちょうどテスト中にすぐに活動を開始避けるため、同様の問題に遭遇しました。あなたは、以下のスニペットのようなあなたのテストルールを調整することによって、これを達成

@Rule 
// Do not launch the activity right away 
public ActivityTestRule<LoginActivity> activityTestRule = new ActivityTestRule(LoginActivity.class, true, false); 

し、テストのセットアップ時に自分でモックWebサーバーを起動することができます。 mockWebServer.url("/")はまだ起動していない場合に備えて模擬サーバを起動しようとするため、基本的に起きています。テスト実行中に後で実行したくない場合は、最初に実行する必要があります(NetworkOnMainThreadExceptionの場合)。

関連する問題