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:
- Extend from InstrumentationTestCase and then call
getInstrumentation().getContext()
- 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
Gesture Detection and Scrollview Issue
How to Enable and Disable a Component
Android Studio- Program Type Already Present: Com.Google.Android.Gms.Internal.Measurement.Zzwp
Android Studio 3.0 Compile Issue (Cannot Choose Between Configurations)
How to Load HTML String in a Webview
Get the Co-Ordinates of a Touch Event on Android
Failed to Read Png Signature: File Does Not Start with Png Signature
How to Use Unicode in Android Resource
How to Dynamically Change an App Icon Like Calendar App Does
How to Make Layouts for Several Android Screen Sizes
How to Programmatically Scroll Android Webview
Android Cardview Remove Padding
How to Retrieve HTML Content from Webview (As a String)
Setting Audio File as Ringtone