How to test file IO in Android unitTest/AndroidTest - android

I am working on improving code coverage of my project and since there is a method I wrote to write file into android internalStorage by using the following code snippet from Android Developer website.
String FILENAME = "hello_file";
String string = "hello world!";
File testFile = new File(context.getFilesDir(), FILENAME);
FileOutputStream fos =new FileOutputStream(file);
fos.write(string.getBytes());
fos.close();
My idea is to assert by reading the file and compare with hello world! and see if they matches to prove that my writing function works in unit test/ Android Instrumentation test. However, it not really straightforward for me to test this because of following
I don't know the path of the file from unit test aspect (JVM)
Not from Android instrumentation test perspective either.
What is the best practice to test this kind of IO functionality in Android? Should I even care about if the file had been created and put? Or I should simply just check if the fos from in not null?
FileOutputStream fos =new FileOutputStream(file);
Please kindly provide me the advices. Thanks.

I wouldn't test that the file is saved - this is not your system and Android AOSP should have tests for making sure the file actually saves. Read more here
What you want to test is if you are telling Android to save your file. Perhaps like this:
String FILENAME = "hello_file";
String string = "hello world!";
File testFile = new File(context.getFilesDir(), FILENAME);
FileOutputStream fos =new FileOutputStream(file);
public void saveAndClose(String data, FileOutputStream fos) {
fos.write(data.getBytes());
fos.close();
}
Then your test would use Mockito for the FOS and be:
FileOutputStream mockFos = Mockito.mock(FileOutputStream.class);
String data = "ensure written";
classUnderTest.saveAndClose(data, mockFos);
verify(mockFos).write(data.getBytes());
second test:
FileOutputStream mockFos = Mockito.mock(FileOutputStream.class);
String data = "ensure closed";
classUnderTest.saveAndClose(data, mockFos);
verify(mockFos).close();

Related

Why do I need add the folder when I get FileInputStream from a file?

I have read the article at https://developer.android.com/guide/topics/data/data-storage.html#filesInternal
The Code A works well, but the Code B doesn't work well, I must use the code inputStream = new FileInputStream(mContext.getFilesDir()+"/hello_file");
Must I add folder when I read the files stored internal storage ?
Code A
String FILENAME = "hello_file";
String string = "hello world!";
FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();
Code B
InputStream inputStream = null;
int size = 0;
try {
inputStream = new FileInputStream("hello_file");
size=inputStream.available();
Utility.LogError("Size Html: "+size );
}catch (Exception e){
Utility.LogError("Error: Input"+e.getMessage() );
}
To get FileStreams use:
openFileInput(String name)
openFileOutput(String name, int mode)
Some Details:
openFileInput openFileOutput are methods of Context.
In Code a you are using openFileOutput. If you check out a src.
You can see that openFileOutput does the following:
...
File f = makeFilename(getFilesDir(), name);
...
FileOutputStream fos = new FileOutputStream(f, append);
...
So the path used to generate the output stream is the same as the path you provided:
mContext.getFilesDir()+"/hello_file"
The mistake In Short:
Code A: will write to: +"/hello_file"
Code B: Tries to read: "/hello_file"

Android Studio Data Collection

I am designing an app for my job to collect data on dog training. I need to be able to access the data on my computer to analyze it. I have completed the front end of the app and organized all of the information into a single string that I would like to save into a file for later analysis. I run the app and can not find the data anywhere on the tablet that runs the app. The code that saves the app is:
String output="Example, Data";
File file = new File(Environment.getExternalStoragePublicDirectory(DIRECTORY_DOCUMENTS),"TrainingData.txt");
try {
FileOutputStream fout = new FileOutputStream(file);
OutputStreamWriter outputStream = new OutputStreamWriter(fout);
outputStream.write(output);
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
Is there something wrong with the saving part of the code listed or is it correct and I'm just failing to find the file on the tablet. Any help would be greatly appreciated.
Try this instead:
File path = context.getFilesDir();
File file = new File(path, "the-file.txt");
and then:
FileOutputStream stream = new FileOutputStream(file);
try {
stream.write(output".getBytes());
} finally {
stream.close();
}

Where should I store a file in Android?

I have an application that creates a configuration file and a log file. I stored these in the external storage, but when I try it in my android emulator it doesn't work because the external storage isn't writable. If this happens, where should I store the files?
This is my code:
private void createConfigurationFile(){
File ssConfigDirectory =
new File(Environment.getExternalStorageDirectory()+"/MyApp/config/");
File file = new File(ssConfigDirectory, mUsername+".cfg");
if(!file.exists()){
try{
String state = Environment.getExternalStorageState();
if (!Environment.MEDIA_MOUNTED.equals(state)){
ssConfigDirectory = new File("PATH_WHERE_I_SHOULD_STORE_IT");
}
File ssLogDirectory = new File(ssConfigDirectory+"/SweetSyncal/log/");
ssLogDirectory.mkdirs();
ssConfigDirectory.mkdirs();
File outputFile = new File(ssConfigDirectory, mUsername+".cfg");
FileOutputStream fOut = new FileOutputStream(outputFile);
OutputStreamWriter osw = new OutputStreamWriter(fOut);
writeFile(osw);
osw.flush();
osw.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
If the file isn't too big you can save it in the device's Internal Storage.
To access the Internal Storage you can use the following method:
FileOutputStream openFileOutput (String name, int mode)
(You need an instance of Context to use it)
Example:
String FILENAME = "hello_file";
String string = "hello world!";
FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();
As to why the code you provided is not working then there are two possibilities:
You forgot to add the required permission (WRITE_EXTERNAL_STORAGE).
You'r emulator doesn't have an SD card enabled. Assuming you are using Eclipse you can enabled it in the AVD Manager. Just edit your AVD instance and type in the size of the SD card in the appropriate field. You should also add a hardware feature called SD Card Support and set it to TRUE.
There is a great article in the official Developer Guide which will tell you everything you need to know about storage in Android.
You can read it HERE

Android create folders in Internal memory issue

I have a little issue with creating folders for my application in Internal Memory. I'm using this piece of code :
public static void createFoldersInInternalStorage(Context context){
try {
File usersFolder = context.getDir("users", Context.MODE_PRIVATE);
File fileWithinMyDir = new File(usersFolder, "users.txt"); //Getting a file within the dir.
FileOutputStream out = new FileOutputStream(fileWithinMyDir); //Use the stream as usual to write into the file.
File dataFolder = context.getDir("data", Context.MODE_PRIVATE);
File fileWithinMyDir2 = new File(dataFolder, "data.txt"); //Getting a file within the dir.
FileOutputStream out2 = new FileOutputStream(fileWithinMyDir2); //Use the stream as usual to write into the file.
File publicFolder = context.getDir("public", Context.MODE_PRIVATE);
File fileWithinMyDir3 = new File(publicFolder, "public.txt"); //Getting a file within the dir.
FileOutputStream out3 = new FileOutputStream(fileWithinMyDir3); //Use the stream as usual to write into the file.
} catch(FileNotFoundException e){
e.printStackTrace();
}
}
So folders are created but in front of their name there is the beginning "app_" : app_users, app_data, app_public. Is there a way to create the folders with the name given by me? And another question : I want to first create folder Documents and than all other folders "Data, Public, Users" on it.... And the last question : How can I give the right folder path if I wanted to create a file in Documents/Users/myfile.txt in Internal Memory?
Thanks in advance!
You can use this :
File myDir = context.getFilesDir();
String filename = "documents/users/userId/imagename.png";
File file = new File(myDir, filename);
file.createNewFile();
file.mkdirs();
FileOutputStream fos = new FileOutputStream(file);
fos.write(mediaCardBuffer);
fos.flush();
fos.close();
Is there a way to create the folders with the name given by me?
Use getFilesDir() and Java file I/O instead of getDir().
How can I give the right folder path if I wanted to create a file in Documents/Users/myfile.txt in Internal Memory?
Use getFilesDir() and Java file I/O, such as the File constructor that takes a File and a String to assemble a path.

Reading a cache file previously written by the same app

I'm writing to a file using the code below:
File file = new File(getCacheDir(), "cachefile");
FileOutputStream fos = new FileOutputStream(file);
StringBuilder cachetext = new StringBuilder();
Iterator bri = brands.iterator();
Iterator bli = brand_id.iterator();
while(bli.hasNext()) {
cachetext.append(bli.next() + "|" + bri.next() + System.getProperty("line.separator"));
}
fos.write(cachetext.toString().getBytes());
fos.close();
This works fine - no errors and the file ends up containing what I expect it to contain. When I go to read it via openFileInput(), however, I get an exception telling me that path separators are not allowed
FileInputStream fis = openFileInput(getCacheDir() + "/cachefile");
Fair enough, that contains a slash, but how else can I specify the path of the file I want to open? There must be a way to do this, of course, but I can't find answers via Google ('read', 'cache' and 'file' not being the most niche of terms ...) so I thought I'd try the human touch. Thanks in advance!
you do it pretty much the same way you created the output file:
FileInputStream fis = new FileInputStream(new File(getCacheDir(), "cachefile"));

Categories

Resources