Reputation: 17557
Does anyone know how can you get the context of the Test project in Android junit test case (extends AndroidTestCase).
Note: The test is NOT instrumentation test.
Note 2: I need the context of the test project, not the context of the actual application that is tested.
I need this to load some files from assets from the test project.
Upvotes: 145
Views: 120718
Reputation: 8067
For Kotlin unit test with @RunWith(AndroidJUnit4::class)
Add this dependency for kotlin test
implementation 'androidx.test:core-ktx:1.5.0'
In the test class access context using the below snippet.
private val context = ApplicationProvider.getApplicationContext<Context>()
Upvotes: 5
Reputation: 597
Add Mocito Library
testImplementation 'junit:junit:4.13.2'
testImplementation 'androidx.test:core:1.4.0'
testImplementation 'org.mockito:mockito-core:3.10.0'
Add Annoatation call @Mock where ever need for example for Context
@RunWith(MockitoJUnitRunner::class)
class EmailValidatorTest {
@Mock
private lateinit var context: Context
lateinit var utils:Utils
@Before
fun launch()
{
utils=Utils(context)
}
@Test
fun emailValidator_NullEmail_ReturnsFalse() {
assertFalse(utils.isValidEmail(null))
}
}
Upvotes: 0
Reputation: 45140
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("com.android.systemui", appContext.getPackageName());
}
}
You can even run it on main thread using runOnMainSync
. Here is the complete solution:
@RunWith(AndroidJUnit4::class)
class AwesomeViewModelTest {
@Test
fun testHandler() {
getInstrumentation().runOnMainSync(Runnable {
val context = InstrumentationRegistry.getInstrumentation().targetContext
// Here you can call methods which have Handler
})
}
}
Upvotes: 8
Reputation: 2566
If you want to get the context with Kotlin and Mockito, you can do it in the following way:
val context = mock(Context::class.java)
Upvotes: 9
Reputation: 2150
For those encountering these problems while creating automated tests, you've gotta do this :
Context instrumentationContext;
@Before
public void method() {
instrumentationContext = InstrumentationRegistry.getInstrumentation().getContext();
MultiDex.install(instrumentationContext);
}
Upvotes: 1
Reputation: 2242
import androidx.test.core.app.ApplicationProvider;
private Context context = ApplicationProvider.getApplicationContext();
Upvotes: 7
Reputation: 3288
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)?
Upvotes: 191
Reputation: 26271
This is to correct way to get the Context. Other methods are already deprecated
import androidx.test.platform.app.InstrumentationRegistry
InstrumentationRegistry.getInstrumentation().context
Upvotes: 5
Reputation: 123
Update: AndroidTestCase
This class was deprecated in API level 24.
Use InstrumentationRegistry
instead. New tests should be written using the Android Testing Support Library. Link to announcement
You should extend from AndroidTestCase instead of TestCase.
AndroidTestCase Class Overview
Extend this if you need to access Resources or other things that depend on Activity Context.
AndroidTestCase - Android Developers
Upvotes: 5
Reputation: 1212
The other answers are outdated. Right now every time that you extend AndroidTestCase, there is mContext Context object that you can use.
Upvotes: 0
Reputation: 9912
As you can read in the AndroidTestCase source code, the getTestContext()
method is hidden.
/**
* @hide
*/
public Context getTestContext() {
return mTestContext;
}
You can bypass the @hide
annotation using reflection.
Just add the following method in your 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;
}
}
Then call getTestContext()
any time you want. :)
Upvotes: 25
Reputation: 4345
After some research the only working solution seems to be the one yorkw pointed out already. You'd have to extend InstrumentationTestCase and then you can access your test application's context using getInstrumentation().getContext() - here is a brief code snippet using the above suggestions:
public class PrintoutPullParserTest extends InstrumentationTestCase {
public void testParsing() throws Exception {
PrintoutPullParser parser = new PrintoutPullParser();
parser.parse(getInstrumentation().getContext().getResources().getXml(R.xml.printer_configuration));
}
}
Upvotes: 39