Search code examples
androidinstrumentation

Accessing a file in InstrumentationTest class


How can I get access to a file for an Instrumentation test without using the AssetManager or a ClassLoader.

I'm doing an integration test on my MediaPlayerFragment which takes in a String representing the filename. I don't want to getInstrumentation().getTargetContext().getResources().getAssets().open(testFile);

or

InputStream in = this.getClass().getClassLoader().getResourceAsStream(file);

because my MediaPlayerFragment takes a filename and makes the FileInputStream itself.

My problem is I keep getting:

FileNotFoundException SC-00.mp3: open failed: ENOENT (No such file or directory).

My test is in:

src/androidTest/java/com.olfybsppa.inglesaventurero.tests/nonUIFragments/MediaPlayerFragment1Test

My asset is in: src/androidTest/assets/SC-00.mp3

I've tried giving the filename as 'assets/SC-00.mp3' and 'androidTest/assets/SC-00.mp3'- no luck.

my sourceSets is

sourceSets {
  main {
    java.srcDirs = ['src/main/java', 'src/main/java/start', 'src/main/java/adapters', 'src/main/java/pagers']
  }
}

but that doesn't work.

I've also tried adding

androidTest {
  java.srcDir 'src/androidTest/assets'
}

to my source sets and that doesn't work.

SIMPLIFICATION 1.

This is a simplified version of my test class. I keep getting a FileNotFoundException. I'm trying to figure out what String filename should be?

public class MediaPlayerFragment1Test
                extends ActivityInstrumentationTestCase2<DefaultActivity> {

  private DefaultActivity mActivity;
  private Instrumentation mInstrumentation;
  private String filename = "file:///androidTest/assets/SC-00.mp3";
  public static String MEDIA_PLAYER_TAG = "MEDIA PLAYER TAG";

  public MediaPlayerFragment1Test() {
    super(DefaultActivity.class);
  }

  @Override
  public void setUp() throws Exception {
    super.setUp();
    mActivity = getActivity();
  }

  public void tearDown() throws Exception {
    super.tearDown();
  }


  @SmallTest
  public void testFileIsAccessible() {
    try {
      FileInputStream fileInputStream = new FileInputStream(filename);
    } catch (IOException e) {
      assertTrue(e instanceof FileNotFoundException);
      assertTrue(false);
    }
  }
}

Solution

  • You can't open an InputStream on an asset normally, because assets are packaged inside your apk. AssetManager.open provides a way to work around this, but you said you don't want to do that.

    If you need a file path which can be opened with a FileInputStream, you could take your asset, copy it to a temporary File and then pass the path of the temp file into your method.

    File temp = File.createTempFile("prefix", "suffix");
    OutputStream out = new FileOutputStream(temp);
    InputStream in = assetManager.open("asset");
    byte[] buffer = new byte[1024];
    int read;
    while((read = in.read(buffer)) != -1){
      out.write(buffer, 0, read);
    }
    String filePath = temp.getPath();
    

    Rember to delete the temp file when you are done.