Getting Context in Androidtestcase or Instrumentationtestcase in Android Studio's Unit Test Feature

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

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)?

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).

Getting a Context for use in AndroidTestCase when class under test is not an activity

There are a few ways around this, you could use a mockcontext as one solution or if you really do not care what the context is just that is valid you can use an InstrumentationTestCase and get the context of the test apk via getInstrumentation().getContext().

I think the reason your context is null is that actually no android context exists at this point, you can get one by creating an application or an activity.

Why in a test class that extends AndroidTestCase, does getContext() return null?

For accessing a context you can:

  1. Extend from InstrumentationTestCase and then call getInstrumentation().getContext()
  2. Use reflection to access a private member

You can see code samples at this answer

Accessing resources in an android test project

I would suggest extending ActivityTestCase instead of AndroidTestCase. You can than access test project resources via

getInstrumentation().getContext().getResources().openRawResource(R.raw.your_res).

Dummy test case example:

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);
}
}

And then in test methods use getInstrumentation().getTargetContext() wherever you used getContext() in your AndroidTestCase extension.

Android NPE running JUnit test

I ended completing my goals of unit testing my sqlite database. The problem seemed to be that I needed to use the build artifact called Android Instrumentation Test instead of the Unit Test build artifact.

I setup a test class in my app/src/androidTest/java directory. The test class extended InstrumentationTestCase.

When I setup my database I use the context provided by getInstrumentation().getTargetContext(). This was important because originally I tried to use getInstrumentation().getContext() and I found that that would always result in a SQLiteCantOpenDatabaseException.

So it seemed my problems occurred because:
1) I wasn't using the correct test artifact
2) I wasn't using the correct test base class
3) I wasn't getting the context correctly



Related Topics



Leave a reply



Submit