I am comparing text files in junit using:
public static void assertReaders(BufferedReader expected,
BufferedReader actual) throws IOException {
String line;
while ((line = expected.readLine()) != null) {
assertEquals(line, actual.readLine());
}
assertNull("Actual had more lines then the expected.", actual.readLine());
assertNull("Expected had more lines then the actual.", expected.readLine());
}
Is this a good way to compare text files? What is preferred?
File file1 = new File("file1. txt"); File file2 = new File("file2. txt"); boolean isTwoEqual = FileUtils. contentEquals(file1, file2);
The assertSame() method tests if two object references point to the same object. 7. void assertNotSame(object1, object2) The assertNotSame() method tests if two object references do not point to the same object.
Here's one simple approach for checking if the files are exactly the same:
assertEquals("The files differ!",
FileUtils.readFileToString(file1, "utf-8"),
FileUtils.readFileToString(file2, "utf-8"));
Where file1
and file2
are File
instances, and FileUtils
is from Apache Commons IO.
Not much own code for you to maintain, which is always a plus. :) And very easy if you already happen to use Apache Commons in your project. But no nice, detailed error messages like in mark's solution.
Edit:
Heh, looking closer at the FileUtils
API, there's an even simpler way:
assertTrue("The files differ!", FileUtils.contentEquals(file1, file2));
As a bonus, this version works for all files, not just text.
junit-addons has nice support for it: FileAssert
It gives you exceptions like:
junitx.framework.ComparisonFailure: aa Line [3] expected: [b] but was:[a]
Here is a more exhaustive list of File comparator's in various 3rd-party Java libraries:
As of 2015, I would recomment AssertJ, an elegant and comprehensive assertion library. For files, you can assert against another file:
@Test
public void file() {
File actualFile = new File("actual.txt");
File expectedFile = new File("expected.txt");
assertThat(actualFile).hasSameTextualContentAs(expectedFile);
}
or against inline strings:
@Test
public void inline() {
File actualFile = new File("actual.txt");
assertThat(linesOf(actualFile)).containsExactly(
"foo 1",
"foo 2",
"foo 3"
);
}
The failure messages are very informative as well. If a line is different, you get:
java.lang.AssertionError:
File:
<actual.txt>
and file:
<expected.txt>
do not have equal content:
line:<2>,
Expected :foo 2
Actual :foo 20
and if one of the files has more lines you get:
java.lang.AssertionError:
File:
<actual.txt>
and file:
<expected.txt>
do not have equal content:
line:<4>,
Expected :EOF
Actual :foo 4
Simple comparison of the content of two files with java.nio.file
API.
byte[] file1Bytes = Files.readAllBytes(Paths.get("Path to File 1"));
byte[] file2Bytes = Files.readAllBytes(Paths.get("Path to File 2"));
String file1 = new String(file1Bytes, StandardCharsets.UTF_8);
String file2 = new String(file2Bytes, StandardCharsets.UTF_8);
assertEquals("The content in the strings should match", file1, file2);
Or if you want to compare individual lines:
List<String> file1 = Files.readAllLines(Paths.get("Path to File 1"));
List<String> file2 = Files.readAllLines(Paths.get("Path to File 2"));
assertEquals(file1.size(), file2.size());
for(int i = 0; i < file1.size(); i++) {
System.out.println("Comparing line: " + i)
assertEquals(file1.get(i), file2.get(i));
}
I'd suggest using Assert.assertThat and a hamcrest matcher (junit 4.5 or later - perhaps even 4.4).
I'd end up with something like:
assertThat(fileUnderTest, containsExactText(expectedFile));
where my matcher is:
class FileMatcher {
static Matcher<File> containsExactText(File expectedFile){
return new TypeSafeMatcher<File>(){
String failure;
public boolean matchesSafely(File underTest){
//create readers for each/convert to strings
//Your implementation here, something like:
String line;
while ((line = expected.readLine()) != null) {
Matcher<?> equalsMatcher = CoreMatchers.equalTo(line);
String actualLine = actual.readLine();
if (!equalsMatcher.matches(actualLine){
failure = equalsMatcher.describeFailure(actualLine);
return false;
}
}
//record failures for uneven lines
}
public String describeFailure(File underTest);
return failure;
}
}
}
}
Matcher pros:
Cons:
FileUtils
sure is a good one. Here's yet another simple approach for checking if the files are exactly the same.
assertEquals(FileUtils.checksumCRC32(file1), FileUtils.checksumCRC32(file2));
While the assertEquals() does provide a little more feedback than the assertTrue(), the result of checksumCRC32() is a long. So, that may not be intrisically helpful.
If expected has more lines than actual, you'll fail an assertEquals before getting to the assertNull later.
It's fairly easy to fix though:
public static void assertReaders(BufferedReader expected,
BufferedReader actual) throws IOException {
String expectedLine;
while ((expectedLine = expected.readLine()) != null) {
String actualLine = actual.readLine();
assertNotNull("Expected had more lines then the actual.", actualLine);
assertEquals(expectedLine, actualLine);
}
assertNull("Actual had more lines then the expected.", actual.readLine());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With