flobacca
flobacca

Reputation: 978

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);
    }
  }
}

Upvotes: 0

Views: 274

Answers (2)

F43nd1r
F43nd1r

Reputation: 7759

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.

Upvotes: 2

Mauker
Mauker

Reputation: 11497

One possible way of doing it is to store the file on the ExternalStorageDirectory, and access it like:

String directory = android.os.Environment.getExternalStorageDirectory().getAbsolutePath();
String filePath = directory + File.separator + "some_file.txt";

try {
        BufferedReader reader = new BufferedReader(new FileReader(filePath));
        // Do something with the reader.
    } catch (IOException e) {
            e.printStackTrace();
            fail();
    }

EDIT: This question might be related.

Second edit: From this question, it seems you have to place your file in the build type you're testing. If it's the debug one, try:

src/debug/res/assets

Upvotes: 0

Related Questions