Home » Android » unit testing – Android InstrumentationTestCase getFilesDir() returns null

unit testing – Android InstrumentationTestCase getFilesDir() returns null

Posted by: admin June 15, 2020 Leave a comment

Questions:

I am using InstrumentationTestCase to unit test a component of my application.

The component persists data to the internal storage and uses Context::fileList(); to retrieve the persisted files.

I experience the following problem: Using this method in the app (on the device) works perfectly fine. But when I try to (Android-)Unit-Test (also on the Device) with use of InstrumentationTestCase I get a NullPointerException inside the fileList() method. I digged into the android source and found out that getFilesDir() (see source here) returns null and causes this error.

The code to reproduce is the following:

public class MyTestCase extends InstrumentationTestCase
{   
    public void testExample() throws Exception
    {
        assertNotNull(getInstrumentation().getContext().getFilesDir()); // Fails
    }
}

My questions are: Is this behaviour intended? What can I do to circumvent this issue? Am I using InstrumentationTestCase right or should I use something different?

I found this question but I’m not sure if this covers the same problem I have.

How to&Answers:

I think that you are right with keeping your test data separate from tested application.

You can fix problem with Null by creating files directory for Instrumentation app by executing the following commands

adb shell
cd /data/data/<package_id_of_instrumentation_app>
mkdir files

You can do above only on emulator or rooted device.

Then test from your question will not fail. I did it and also uploaded file named tst.txt to files dir, all below tests were successful:

assertNotNull(getInstrumentation().getContext().getFilesDir());
assertNotNull(getInstrumentation().getContext().openFileInput("tst.txt"));
assertNotNull(getInstrumentation().getContext().openFileOutput("out.txt", Context.MODE_PRIVATE));

But I think more convenient way to provide data to test project is to use assets of test project where you can simply save some files and open them:

assertNotNull(getInstrumentation().getContext().getAssets().open("asset.txt"));

or if you want to save some results of tests to the file you can use ExternalStorage:

File extStorage = Environment.getExternalStorageDirectory();
assertNotNull(extStorage);

Answer:

@Blackbelt mentioned in his comment to use getTargetContext() instead of getContext(). I missed the comment, and after a few hours, of trying to figure out how to Realm.init() from an Android instrumented tests, I find out that I need the Context from getTargetContext()…(along the way, i tried to context.filesDir.mkdirs())

package com.github.ericytsang

import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Test

class InstrumentedTest {

    private val context = InstrumentationRegistry.getInstrumentation().targetContext

    @Test
    fun can_mkdirs() {
        assert(context.filesDir.mkdirs())
    }
}