In the past few days I had a little bit of a problem: InstrumentationTestCase gives access to local assets while AndroidTestCase gives access to getAssets() for assets specific to testing.
I had a scenario to test where I get a file from my local src/androidTest/assets directory while the code would need to write some files in /data/data/my.package.name.test/files directory. Quite unfortunate I'd say.
My solution was to create an InputStream method based on this answer, to cover both cases.
The code is:
private InputStream getAssetStream(Context context, String fileName)
throws IOException {
InputStream result;
try {
result = context.getResources().getAssets().open(fileName);
} catch (IOException e) {
result = this.getClass()
.getClassLoader()
.getResourceAsStream("assets" + File.separator + fileName);
}
if (result == null)
throw new IOException(
String.format("Asset file [%s] not found.",
fileName)
);
return result;
}
This way, if the method is called from an InstrumentationTestCase , the first call will get the right result because, as I've mentioned above, InstrumentationTestCase gives us access to local assets. If called from an AndroidTestCase , the first path will get a FileNotFoundException and the second variant will try to get the file from the class loader. Normally, only the two options can happen; the second one fails only if the classpath is missing the test content (which it shouldn't).
Member discussion: