Get Context of Test Project in Android Junit Test Case

Get context of test project in Android junit test case

There's new approach with Android Testing Support Library (currently androidx.test:runner:1.1.1). Kotlin updated example:

class ExampleInstrumentedTest {

lateinit var instrumentationContext: Context

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

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

If you want also app context run:

InstrumentationRegistry.getInstrumentation().targetContext

Full running example: https://github.com/fada21/AndroidTestContextExample

Look here: What's the difference between getTargetContext() and getContext (on InstrumentationRegistry)?

Getting context in AndroidTestCase or InstrumentationTestCase in Android Studio's Unit Test feature

Updated - Please use Espresso for writing instrumentation tests

Newer Examples:

I got these working without deploying to a device. Put the tests in the /src/main/test/ folder.

Here are newer examples, I took your examples and tested them in my own temporary test project. I ran the tests via command line: ./gradlew clean test. Please read more here: https://sites.google.com/a/android.com/tools/tech-docs/unit-testing-support.

Top build.gradle:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.1.3'

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

allprojects {
repositories {
jcenter()
}
}

App build.gradle:

apply plugin: 'com.android.application'

android {
compileSdkVersion 22
buildToolsVersion "22.0.0"

defaultConfig {
applicationId "com.test"
minSdkVersion 9
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}

testOptions { // <-- You need this
unitTests {
returnDefaultValues = true
}
}
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.0.0'

testCompile 'junit:junit:4.12' // <-- You need this
}

Basic Tests:

InstrumentationTestCaseTest to test Context and Assertions.

import android.content.Context;
import android.test.InstrumentationTestCase;
import android.test.mock.MockContext;

public class InstrumentationTestCaseTest extends InstrumentationTestCase {

Context context;

public void setUp() throws Exception {
super.setUp();

context = new MockContext();

assertNotNull(context);

}

public void testSomething() {

assertEquals(false, true);
}

}

ActivityTestCase to test your Resources.

import android.content.Context;
import android.content.res.Resources;
import android.test.ActivityTestCase;

public class ActivityTestCaseTest extends ActivityTestCase {

public void testFoo() {

Context testContext = getInstrumentation().getContext();
Resources testRes = testContext.getResources();

assertNotNull(testRes);
assertNotNull(testRes.getString(R.string.app_name));
}
}

AndroidTestCase to test Context and Assertions.

import android.content.Context;
import android.test.AndroidTestCase;
import android.test.mock.MockContext;

public class AndroidTestCaseTest extends AndroidTestCase {

Context context;

public void setUp() throws Exception {
super.setUp();

context = new MockContext();

setContext(context);

assertNotNull(context);

}

// Fake failed test
public void testSomething() {
assertEquals(false, true);
}
}

Googling Old Examples:

After Googling a lot bout this error, I believe your bet is to use getInstrumentation().getContext().getResources().openRawResource(R.raw.your_res). or something similar in order to test your resources.

Using InstrumentationTestCase:

Test Resources:

public class PrintoutPullParserTest extends InstrumentationTestCase {

public void testParsing() throws Exception {
PrintoutPullParser parser = new PrintoutPullParser();
parser.parse(getInstrumentation().getContext().getResources().getXml(R.xml.printer_configuration));
}
}

Source: https://stackoverflow.com/a/8870318/950427 and https://stackoverflow.com/a/16763196/950427

Using ActivityTestCase:

Test Resources:

public class Test extends ActivityTestCase {

public void testFoo() {

// .. test project environment
Context testContext = getInstrumentation().getContext();
Resources testRes = testContext.getResources();
InputStream ts = testRes.openRawResource(R.raw.your_res);

assertNotNull(testRes);
}
}

Source: https://stackoverflow.com/a/9820390/950427

Using AndroidTestCase:

Getting the Context (a simple hack):

private Context getTestContext() {
try {
Method getTestContext = ServiceTestCase.class.getMethod("getTestContext");
return (Context) getTestContext.invoke(this);
} catch (final Exception exception) {
exception.printStackTrace();
return null;
}
}

Source: https://stackoverflow.com/a/14232913/950427

But, if you look a the source code of AndroidTestCase, it looks like you need to set a Context yourself:

Source: http://alvinalexander.com/java/jwarehouse/android/core/java/android/test/AndroidTestCase.java.shtml

Android JUnit4 Testing - Where to get Context from?

As described here: https://code.google.com/p/android-test-kit/wiki/AndroidJUnitRunnerUserGuide
Use the InstrumentationRegistry to obtain the context.

However if you call InstrumentationRegistry.getContext() directly you may get an exception opening your database. I believe this is because the context returned by getContext() points to the instrumentation's context rather than that of your application / unit test. Instead use InstrumentationRegistry.getInstrumentation().getTargetContext()

For example:

@RunWith(AndroidJUnit4.class)
public class SqliteTest {

Context mMockContext;

@Before
public void setUp() {
mMockContext = new RenamingDelegatingContext(InstrumentationRegistry.getTargetContext(), "test_");
}
}

The RenamingDelegatingContext simply prefixes the file/database names with test_ to prevent you from overwriting data that you may have in the same simulator.

Android Unit Tests Requiring Context

You might try switching to AndroidTestCase. From looking at the docs, it seems like it should be able to provide you with a valid Context to pass to SQLiteOpenHelper.

Edit:
Keep in mind that you probably have to have your tests setup in an "Android Test Project" in Eclipse, since the tests will try to execute on the emulator (or real device).

JUnit Local Test - Android Context 'No instrumentation registered!'

Solution

Refactor AndroidViewModel implementation to ViewModel as outlined in Jose Alcérreca's post Locale changes and the AndroidViewModel antipattern

This refactor will remove the need to create Application Context.

In addition to the ViewModel refactor, pass components into the ViewModel as an argument to separate dependencies. A Dependency Injection library may be used in the new ViewModel in order to create required components (ie — Repository, Database, Analytics, and etc.) and de-couple them from the ViewModel as well.



Related Topics



Leave a reply



Submit