Getting context in AndroidTestCase or InstrumentationTestCase in Android Studio's Unit Test feature
Solution 1:
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
Solution 2:
With the Android Testing Support Library, you can
- get test apk context with
InstrumentationRegistry.getContext()
- get app apk context with
InstrumentationRegistry.getTargetContext()
- get Instrumentation with
InstrumentationRegistry.getInstrumentation()
See the bottom of the linked page for how to add Testing Support library to your project.
Solution 3:
Here is a recent way to setup (unit) instrumentation tests
Setup
In your build.gradle add:
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
and the following dependencies:
// Instrumentation tests
androidTestImplementation "com.android.support.test:runner:$supportTestRunnerVersion"
// To use assertThat syntax
androidTestImplementation "org.assertj:assertj-core:$assertJVersion"
Example class
public class Example {
public Object doSomething() {
// Context is used here
}
}
Example test
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(AndroidJUnit4.class)
public class ExampleTest {
private Context context;
@Before
public void setUp() {
// In case you need the context in your test
context = InstrumentationRegistry.getTargetContext();
}
@Test
public void doSomething() {
Example example = new Example();
assertThat(example.doSomething()).isNotNull();
}
}
Documentation
- Building Instrumented Unit Tests | Android Developers
Solution 4:
I was receiving an error when trying to make calls to SQLite using @taynguyen answer, so instead of:
InstrumentationRegistry.getContext()
I used:
InstrumentationRegistry.getTargetContext()
In order to get my target application context instead of the Instrumentation context.