web-dev-qa-db-ja.com

MockitoUri.parseは常にnullを返します

私はこの生産方法を持っています:

public boolean onShouldOverrideUrlLoading(String url) {
    boolean isConsumed = false;
    if (url.contains("code=")) {
         Uri uri = Uri.parse(url);
         String authCode = uri.getQueryParameter("code");
         mView.authCodeObtained(authCode);
         isConsumed = true;
    }
    return isConsumed;
}

そして、私はこのMockitoテスト方法を持っています:

@Test
public void onShouldOverrideUrlLoadingOnAuthCodeObtained(){

    String code = "someCode";

    boolean isConsumed = mPresenter.onShouldOverrideUrlLoading("http://localhost/?code=" + code);

    verify(mView, times(1)).authCodeObtained(code);
    assertEquals(isConsumed, true);
}

しかし、コードが実行されてUri.parse(url)に到達すると、nullポインターを取得するようです。何が足りないのですか?本番環境では、これは完全に機能します。テスト時のみ、Uri.parse()はnullを返します。

ありがとうございました!

11
Alon Minski

テストされるコードは静的コード(Uri.parse(...))であるため、問題はおそらくUriクラスにあり、Uriはおそらくテスト環境で正しく初期化されていません。 Android SDK:に2つのuriクラスがあることに注意してください。

私はAndroid開発者ではありませんが、テスト環境を確認することをお勧めします。

0
Brice

最終的に、私はMockitoの上にPowerMockを使用して、Uriクラスをモックしました。これらの依存関係を使用して追加します。

'org.powermock:powermock-api-mockito:1.4.12'
'org.powermock:powermock-module-junit4:1.6.2'

それについて読んでください ここ

静的メソッド、プライベートメソッド、最終クラスなどをモックすることができます。私のテスト方法では、次のものを使用しました。

PowerMockito.mockStatic(Uri.class);
Uri uri = mock(Uri.class);

PowerMockito.when(Uri.class, "parse", anyString()).thenReturn(uri);

これは実際のコードの行を通過し、テストを進めることができるようにモックされたURIオブジェクトを返しました。必ず追加してください:

@RunWith(PowerMockRunner.class)
@PrepareForTest({Uri.class})

テストクラス名の上に注釈として。

Robolectricを使用してこの問題に取り組むことも有効な手法です。

これが何かに役立つことを願っています。

18
Alon Minski

ここでの問題は、単体テストの実行に使用されるAndroid.jarファイルに実際のコードが含まれていないという事実です。このように、Android.net.Uriはデフォルトでnullを返します。

Android {
  // ...
  testOptions { 
    unitTests.returnDefaultValues = true
  }
}

メソッドのデフォルトの戻り値はまだnullであるため、この場合の問題は解決されません。

私にとっての解決策は、 nmock プラグインを使用することでした。このプラグインの唯一の目的は、Android.jarからいくつかのクラス/パッケージのモックを解除し、それらの完全な実装を提供することです。

この特定のケースでは、スニペットをbuild.gradleファイルに追加するだけです。

apply plugin: 'de.mobilej.unmock'
 //...
unMock {
    keepStartingWith "Android.net.Uri"
}
4
Felipe Conde

Robolectricテストランナーを使用してこれを回避しました。

@RunWith(RobolectricGradleTestRunner::class)
@Config(constants = BuildConfig::class, sdk = intArrayOf(19))
class WeekPageViewModelConverterTests {
...
}
3
Brice Pollock

Android.net.Uriクラスを使用する場合は、Mockitoの上でRobolectric( http://robolectric.org )を使用してテストを実行する必要があります。

1
VinceFR

Android.net.Uriクラスでテストを行うときに同様の問題が発生しました。

テストを「test」フォルダーから「androidTest」に移動してデバイスで実行する際の問題を解決しました。デバイスでは、Uriクラスは正常に動作します。

1
iuri

「@RunWith(RobolectricTestRunner :: class)」でテストスイートを実行することで問題を解決しました

0
prago