Holen Sie sich den Kontext des Testprojekts im Android Junit-Testfall

107

Weiß jemand, wie man den Kontext des Testprojekts im Android Junit-Testfall abruft (erweitert AndroidTestCase).

Hinweis: Der Test ist KEIN Instrumentierungstest.

Hinweis 2: Ich benötige den Kontext des Testprojekts, nicht den Kontext der tatsächlich getesteten Anwendung.

Ich benötige dies, um einige Dateien aus Assets aus dem Testprojekt zu laden.

Peceps
quelle
Warum können Sie InstrumentationTestCase nicht einfach verwenden?
Yorkw
1
Weil ich Dienste teste, nicht UI.
Peceps
1
Hier gibt es eine bessere Antwort: [Verwenden von AndroidTestCase anstelle eines JUnit-Tests] [1] [1]: stackoverflow.com/questions/3170706/…
Jaime Botero

Antworten:

135

Es gibt einen neuen Ansatz mit der Android Testing Support Library (derzeit androidx.test:runner:1.1.1). Kotlin aktualisiertes Beispiel:

class ExampleInstrumentedTest {

    lateinit var instrumentationContext: Context

    @Before
    fun setup() {
        instrumentationContext = InstrumentationRegistry.getInstrumentation().context
    }

    @Test
    fun someTest() {
        TODO()
    }
}

Wenn Sie auch App-Kontext ausführen möchten:

InstrumentationRegistry.getInstrumentation().targetContext

Vollständiges Beispiel: https://github.com/fada21/AndroidTestContextExample

Schauen Sie hier: Was ist der Unterschied zwischen getTargetContext () und getContext (in InstrumentationRegistry)?

fada21
quelle
Endlich eine Antwort zur Verwendung von JUnit4 mit InstrumentationTest. Nach stundenlangem Suchen. Ich muss die Android-Entwicklung lieben.
Fabian Zeindl
1
Nett! tx (beachten Sie, dass es einen Tippfehler in Ihrem Klassenmitglied gibt)
Greg
1
Könnte jemand helfen, welche Abhängigkeiten in die Gradle-Datei eingefügt werden müssen, damit dies funktioniert?
Greg
1
Vergessen Sie nicht, zu compile "com.android.support.test:runner:1.0.1"Ihrem gradle hinzuzufügen
egorikem
2
Es ist veraltet, verwenden Sie InstrumentationRegistry.getInstrumentation().contextstattdessen.
Allan Veloso
37

Nach einigen Recherchen scheint die einzige funktionierende Lösung die zu sein, auf die Yorkw bereits hingewiesen hat. Sie müssten InstrumentationTestCase erweitern und können dann mit getInstrumentation () auf den Kontext Ihrer Testanwendung zugreifen. GetContext () - hier ist ein kurzer Codeausschnitt mit den obigen Vorschlägen:

public class PrintoutPullParserTest extends InstrumentationTestCase {

    public void testParsing() throws Exception {
        PrintoutPullParser parser = new PrintoutPullParser();
        parser.parse(getInstrumentation().getContext().getResources().getXml(R.xml.printer_configuration));
    }
}
AgentKnopf
quelle
7
Ja, aber es scheint albern, dass Android in einfachen JUnit-Tests keinen Zugriff auf den Testprojektkontext bietet. Der Kontext befindet sich in AndroidTestCase.mTestContext, ist jedoch privat. Ich verstehe nicht warum.
Peceps
@peceps Full Ack - aber so ist es eben und ich mag es auch nicht;)
AgentKnopf
25

Wie Sie im AndroidTestCase-Quellcode lesen können , ist die getTestContext()Methode ausgeblendet.

/**
 * @hide
 */
public Context getTestContext() {
    return mTestContext;
}

Sie können die @hideAnmerkung mithilfe der Reflexion umgehen .

Fügen Sie einfach die folgende Methode hinzu AndroidTestCase:

/**
 * @return The {@link Context} of the test project.
 */
private Context getTestContext()
{
    try
    {
        Method getTestContext = ServiceTestCase.class.getMethod("getTestContext");
        return (Context) getTestContext.invoke(this);
    }
    catch (final Exception exception)
    {
        exception.printStackTrace();
        return null;
    }
}

Dann rufen Sie getTestContext()jederzeit an. :) :)

Timothée Jeannin
quelle
2
Funktionierte perfekt für mich und ich lade Assets mit Context entweder von AndroidTestCase über diese Methode oder ActivityInstrumentationTestCase2.getInstrumentation () .getContext (), dann getResources () .getAssets ()
Andrew Mackenzie
Können Sie darüber spekulieren, warum sie es versteckt haben? Wenn wir diese Technik verwenden, könnten sie die Methode in einer späteren Version entfernen (unseren Testcode brechen)?
Andrew Shepherd
1
Ich bekommejava.lang.NoSuchMethodException: android.test.ServiceTestCase.getTestContext()
kurdtpage
4

Update: AndroidTestCase Diese Klasse war in API-Level 24 veraltet. Verwenden Sie InstrumentationRegistrystattdessen. Neue Tests sollten mithilfe der Android Testing Support Library geschrieben werden. Link zur Ankündigung

Sie sollten von AndroidTestCase anstelle von TestCase erweitern.

Übersicht über die AndroidTestCase-Klasse
Erweitern Sie diese Option, wenn Sie auf Ressourcen oder andere Dinge zugreifen müssen, die vom Aktivitätskontext abhängen.

AndroidTestCase - Android-Entwickler

eslamb
quelle
4

Wenn Sie den Kontext mit Kotlin und Mockito erhalten möchten, können Sie dies folgendermaßen tun:

val context = mock(Context::class.java)

Ich hoffe es hilft dir

Juanes30
quelle
im Kontext null bekommen?
Deven
Und vergessen Sie nicht, Ihre Testklasse mit @RunWith (MockitoJUnitRunner :: class)
USMAN osman
2

Dies dient dazu, den Kontext zu korrigieren. Andere Methoden sind bereits veraltet

import androidx.test.platform.app.InstrumentationRegistry

InstrumentationRegistry.getInstrumentation().context
Tomrozb
quelle
2
import androidx.test.core.app.ApplicationProvider;

    private Context context = ApplicationProvider.getApplicationContext();
eoinzy
quelle
1

Wenn Sie beim Erstellen automatisierter Tests auf diese Probleme stoßen, müssen Sie Folgendes tun:

    Context instrumentationContext;

    @Before
    public void method() {

        instrumentationContext = InstrumentationRegistry.getInstrumentation().getContext();

        MultiDex.install(instrumentationContext);
    }
Sebastien FERRAND
quelle
0

Die anderen Antworten sind veraltet. Jedes Mal, wenn Sie AndroidTestCase erweitern, können Sie ein mContext Context-Objekt verwenden.

Yoni Keren
quelle