2015-08-16 8 views
6

ich dieses Herstellungsverfahren haben:Mockito Uri.parse gibt immer 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; 
} 

Und ich habe diese Mockito Testmethode:

@Test 
public void onShouldOverrideUrlLoadingOnAuthCodeObtained(){ 

    String code = "someCode"; 

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

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

Aber es scheint, wenn der Code ausgeführt wird und es erreicht Uri. Parse (URL), bekomme ich einen Nullzeiger. Was vermisse ich? In der Produktion funktioniert das perfekt. Nur beim Testen gibt Uri.parse() null zurück.

Vielen Dank!

+0

Das Problem wahrscheinlich in Uri ist, ist es wahrscheinlich in der Testumgebung schlecht initialisieren. Wir 'Uri' existiert nicht im Android SDK [' URI'] (https://developer.android.com/reference/java/net/URI.html#create (java.lang.String)). Es scheint also nicht wie eine Versandklasse, das könnte das Problem sein. Nichts, was mit Mockito zu tun hat. – Brice

+0

@Brice Danke. Ja, das schien das Problem zu sein. Sie sollten dies als Antwort posten. Die Uri-Klasse kommt von Android. Also hat Mockito Schwierigkeiten, damit zu arbeiten. –

+0

fertig :) Hoffe, dass geholfen hat. – Brice

Antwort

1

Das Problem liegt wahrscheinlich in Uri Klasse, wie der Code getestet wird, ist statische Code (Uri.parse(...)), Uri ist wahrscheinlich schlecht in der Testumgebung zu initialisieren. Hinweis: Es gibt im Android SDK zwei uri Klassen ist:

Ich bin kein Android-Entwickler, aber Sie können die Testumgebung überprüfen möchten.

+0

Wie hast du das Problem genau gelöst? Wie initialisiere ich meine Testumgebung in Android richtig? – Johannes

+0

@ user59442 Ich kann dir nicht antworten, ich bin kein _Android Entwickler_. Stellen Sie stattdessen den Autor der Frage Alon Minski! – Brice

11

Schließlich ich PowerMock oben auf Mockito verwendet ausführen, um die Uri-Klasse zu verspotten. diese dependecies Verwenden Sie es hinzuzufügen:

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

Lesen Sie darüber here.

Es ermöglicht Ihnen, statische Methoden, private Methoden, letzte Klassen und vieles mehr zu verspotten. Ich In meinem Test-Methode verwendet:

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

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

Dadurch wird die Linie in den eigentlichen Code übergeben und hat einen Mocked Uri Objekt so der Test vorwärts bewegen konnte. Stellen Sie sicher, hinzuzufügen:

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

als Anmerkungen auf dem Testklasse Namen.

Die Verwendung von Robolectric zur Lösung dieses Problems ist ebenfalls eine gültige Methode.

Hoffe das hilft etwas was.

0

Ich bin mit dem Roboelectric Test Runner dazu gekommen.

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

Ich hatte ein ähnliches Problem Tests mit android.net.Uri Klasse.

Ich habe das Problem gelöst, indem ich den Test aus dem Ordner 'test' nach 'androidTest' verschoben und auf dem Gerät ausgeführt habe. Im Gerät verhält sich die Klasse Uri normal.

1

Das Problem hierbei ist die Tatsache, dass android.jar-Datei, die Unit-Tests verwendet wird, laufen enthält keinen eigentlichen Code. Auf diese Weise android.net.Uri wird null standardmäßig zurückgeben und mit

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

wird das Problem für diesen Fall nicht lösen, da Standardrückgabewert für die Methode noch null

Die Lösung für mich war die Unmock Plugin zu verwenden, die Der einzige Zweck besteht darin, einige der Klassen/Pakete von android.jar zu entfernen und die vollständige Implementierung für diese anzugeben.

In diesem speziellen Fall, fügen Sie einfach den Code-Schnipsel Sie build.gradle Datei

apply plugin: 'de.mobilej.unmock' 
//... 
unMock { 
    keepStartingWith "android.net.Uri" 
} 
Verwandte Themen