我使用以下方法比较junit中的文本文件:
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());
}
这是比较文本文件的好方法吗?什么是首选?
答案 0 :(得分:41)
这是检查文件完全是否相同的一种简单方法:
assertEquals("The files differ!",
FileUtils.readFileToString(file1, "utf-8"),
FileUtils.readFileToString(file2, "utf-8"));
其中file1
和file2
为File
个实例,FileUtils
来自Apache Commons IO。
没有太多自己的代码供您维护,这总是一个加号。 :)如果您已经在项目中使用Apache Commons,那么非常简单。但没有像mark's solution中那样详细的错误消息。
修改强>:
嘿,仔细观察FileUtils
API,有一个偶数simpler way:
assertTrue("The files differ!", FileUtils.contentEquals(file1, file2));
作为奖励,此版本适用于所有文件,而不仅仅是文本。
答案 1 :(得分:31)
junit-addons对此有很好的支持:FileAssert
它为您提供了以下例外:
junitx.framework.ComparisonFailure: aa Line [3] expected: [b] but was:[a]
答案 2 :(得分:19)
以下是各种第三方Java库中文件比较器的更详尽列表:
答案 3 :(得分:13)
截至2015年,我推荐AssertJ,这是一个优雅而全面的断言库。对于文件,您可以对另一个文件断言:
@Test
public void file() {
File actualFile = new File("actual.txt");
File expectedFile = new File("expected.txt");
assertThat(actualFile).hasSameContentAs(expectedFile);
}
或反对内联字符串:
@Test
public void inline() {
File actualFile = new File("actual.txt");
assertThat(linesOf(actualFile)).containsExactly(
"foo 1",
"foo 2",
"foo 3"
);
}
失败消息也非常有用。如果一条线不同,你会得到:
java.lang.AssertionError:
File:
<actual.txt>
and file:
<expected.txt>
do not have equal content:
line:<2>,
Expected :foo 2
Actual :foo 20
如果其中一个文件包含更多行:
java.lang.AssertionError:
File:
<actual.txt>
and file:
<expected.txt>
do not have equal content:
line:<4>,
Expected :EOF
Actual :foo 4
答案 4 :(得分:7)
我建议使用Assert.assertThat和hamcrest matcher(junit 4.5或更高版本 - 甚至可能是4.4)。
我最终会得到类似的东西:
assertThat(fileUnderTest, containsExactText(expectedFile));
我的匹配器在哪里:
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专业人士:
缺点:
答案 5 :(得分:5)
FileUtils
肯定是个好人。这是另一个simple approach,用于检查文件是否完全相同。
assertEquals(FileUtils.checksumCRC32(file1), FileUtils.checksumCRC32(file2));
虽然assertEquals()确实提供了比assertTrue()更多的反馈,但checksumCRC32()的结果很长。所以,这可能没有多大帮助。
答案 6 :(得分:5)
使用java.nio.file API对两个文件的内容进行Simpel比较。
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);
或者如果您想比较各个行:
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));
}
答案 7 :(得分:4)
如果预期有更多行而不是实际行,那么在稍后到达assertNull之前,你将失败一个assertEquals。
虽然很容易解决:
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());
}
答案 8 :(得分:0)
这是我自己的equalFiles
实现,无需向项目中添加任何库。
private static boolean equalFiles(String expectedFileName,
String resultFileName) {
boolean equal;
BufferedReader bExp;
BufferedReader bRes;
String expLine ;
String resLine ;
equal = false;
bExp = null ;
bRes = null ;
try {
bExp = new BufferedReader(new FileReader(expectedFileName));
bRes = new BufferedReader(new FileReader(resultFileName));
if ((bExp != null) && (bRes != null)) {
expLine = bExp.readLine() ;
resLine = bRes.readLine() ;
equal = ((expLine == null) && (resLine == null)) || ((expLine != null) && expLine.equals(resLine)) ;
while(equal && expLine != null)
{
expLine = bExp.readLine() ;
resLine = bRes.readLine() ;
equal = expLine.equals(resLine) ;
}
}
} catch (Exception e) {
} finally {
try {
if (bExp != null) {
bExp.close();
}
if (bRes != null) {
bRes.close();
}
} catch (Exception e) {
}
}
return equal;
}
使用它只需使用常规AssertTrue
JUnit方法
assertTrue(equalFiles(expected, output)) ;