diff --git a/test/data/StorageFileTest/InvalidData.txt b/test/data/StorageFileTest/InvalidData.txt
new file mode 100644
index 000000000..91e8971a4
--- /dev/null
+++ b/test/data/StorageFileTest/InvalidData.txt
@@ -0,0 +1,6 @@
+
+
+
+ data
+
+
diff --git a/test/data/StorageFileTest/ValidData.txt b/test/data/StorageFileTest/ValidData.txt
new file mode 100644
index 000000000..968fccfdc
--- /dev/null
+++ b/test/data/StorageFileTest/ValidData.txt
@@ -0,0 +1,19 @@
+
+
+
+ John Doe
+ 98765432
+ johnd@gmail.com
+ John street, block 123, #01-01
+
+
+ Betsy Crowe
+ 1234567
+ betsycrowe@gmail.com
+ Newgate Prison
+ friend
+ criminal
+
+ friend
+ criminal
+
diff --git a/test/java/seedu/addressbook/storage/StorageFileTest.java b/test/java/seedu/addressbook/storage/StorageFileTest.java
new file mode 100644
index 000000000..1bd6fcab3
--- /dev/null
+++ b/test/java/seedu/addressbook/storage/StorageFileTest.java
@@ -0,0 +1,109 @@
+package seedu.addressbook.storage;
+
+import static org.junit.Assert.assertEquals;
+import java.nio.file.Paths;
+import java.util.Collections;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.rules.TemporaryFolder;
+
+import seedu.addressbook.data.AddressBook;
+import seedu.addressbook.data.exception.IllegalValueException;
+import seedu.addressbook.data.person.Address;
+import seedu.addressbook.data.person.Email;
+import seedu.addressbook.data.person.Name;
+import seedu.addressbook.data.person.Person;
+import seedu.addressbook.data.person.Phone;
+import seedu.addressbook.data.tag.Tag;
+import seedu.addressbook.data.tag.UniqueTagList;
+import seedu.addressbook.storage.StorageFile.StorageOperationException;
+import static seedu.addressbook.util.TestUtil.assertTextFilesEqual;
+
+public class StorageFileTest {
+ private static final String TEST_DATA_FOLDER = "test/data/StorageFileTest";
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Rule
+ public TemporaryFolder testFolder = new TemporaryFolder();
+
+ @Test
+ public void constructor_nullFilePath_exceptionThrown() throws Exception {
+ thrown.expect(NullPointerException.class);
+ new StorageFile(null);
+ }
+
+ @Test
+ public void constructor_noTxtExtension_exceptionThrown() throws Exception {
+ thrown.expect(IllegalValueException.class);
+ new StorageFile(TEST_DATA_FOLDER + "/" + "InvalidfileName");
+ }
+
+ @Test
+ public void load_invalidFormat_exceptionThrown() throws Exception {
+ // The file contains valid xml data, but does not match the AddressBook class
+ StorageFile storage = getStorage("InvalidData.txt");
+ thrown.expect(StorageOperationException.class);
+ storage.load();
+ }
+
+ @Test
+ public void load_validFormat() throws Exception {
+ AddressBook actualAB = getStorage("ValidData.txt").load();
+ AddressBook expectedAB = getTestAddressBook();
+
+ // ensure loaded AddressBook is properly constructed with test data
+ // TODO: overwrite equals method in AddressBook class and replace with equals method below
+ assertEquals(actualAB.getAllPersons(), expectedAB.getAllPersons());
+ }
+
+ @Test
+ public void save_nullAddressBook_exceptionThrown() throws Exception {
+ StorageFile storage = getTempStorage();
+ thrown.expect(NullPointerException.class);
+ storage.save(null);
+ }
+
+ @Test
+ public void save_validAddressBook() throws Exception {
+ AddressBook ab = getTestAddressBook();
+ StorageFile storage = getTempStorage();
+ storage.save(ab);
+
+ assertStorageFilesEqual(storage, getStorage("ValidData.txt"));
+ }
+
+ // getPath() method in StorageFile class is trivial so it is not tested
+
+ /**
+ * Asserts that the contents of two storage files are the same.
+ */
+ private void assertStorageFilesEqual(StorageFile sf1, StorageFile sf2) throws Exception {
+ assertTextFilesEqual(Paths.get(sf1.getPath()), Paths.get(sf2.getPath()));
+ }
+
+ private StorageFile getStorage(String fileName) throws Exception {
+ return new StorageFile(TEST_DATA_FOLDER + "/" + fileName);
+ }
+
+ private StorageFile getTempStorage() throws Exception {
+ return new StorageFile(testFolder.getRoot().getPath() + "/" + "temp.txt");
+ }
+
+ private AddressBook getTestAddressBook() throws Exception {
+ AddressBook ab = new AddressBook();
+ ab.addPerson(new Person(new Name("John Doe"),
+ new Phone("98765432", false),
+ new Email("johnd@gmail.com", false),
+ new Address("John street, block 123, #01-01", false),
+ new UniqueTagList(Collections.emptySet())));
+ ab.addPerson(new Person(new Name("Betsy Crowe"),
+ new Phone("1234567", true),
+ new Email("betsycrowe@gmail.com", false),
+ new Address("Newgate Prison", true),
+ new UniqueTagList(new Tag("friend"), new Tag("criminal"))));
+ return ab;
+ }
+}
diff --git a/test/java/seedu/addressbook/util/TestUtil.java b/test/java/seedu/addressbook/util/TestUtil.java
new file mode 100644
index 000000000..18fbfba7a
--- /dev/null
+++ b/test/java/seedu/addressbook/util/TestUtil.java
@@ -0,0 +1,20 @@
+package seedu.addressbook.util;
+
+import static org.junit.Assert.assertEquals;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+
+public class TestUtil {
+ /**
+ * Asserts whether the text in the two given files are the same. Ignores any
+ * differences in line endings
+ */
+ public static void assertTextFilesEqual(Path path1, Path path2) throws IOException {
+ List list1 = Files.readAllLines(path1, Charset.defaultCharset());
+ List list2 = Files.readAllLines(path2, Charset.defaultCharset());
+ assertEquals(String.join("\n", list1), String.join("\n", list2));
+ }
+}