Java 将文本文件与 Junit 进行比较
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/466841/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Comparing text files with Junit
提问by jon077
I am comparing text files in junit using:
我正在使用以下方法比较 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());
}
Is this a good way to compare text files? What is preferred?
这是比较文本文件的好方法吗?什么是首选?
采纳答案by IAdapter
junit-addonshas nice support for it: FileAssert
junit-addons对它有很好的支持:FileAssert
It gives you exceptions like:
它为您提供以下例外情况:
junitx.framework.ComparisonFailure: aa Line [3] expected: [b] but was:[a]
回答by Jon Skeet
If expected has more lines than actual, you'll fail an assertEquals before getting to the assertNull later.
如果预期的行数多于实际行数,则在稍后到达 assertNull 之前,您将失败 assertEquals。
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());
}
回答by Stephen
I'd suggest using Assert.assertThat and a hamcrest matcher(junit 4.5 or later - perhaps even 4.4).
我建议使用 Assert.assertThat 和hamcrest 匹配器(junit 4.5 或更高版本 - 甚至可能是 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:
匹配器优点:
- Composition and reuse
- Use in normal code as well as test
- Collections
- Used in mock framework(s)
- Can be used a general predicate function
- Really nice log-ability
- Can be combined with other matchers and descriptions and failure descriptions are accurate and precise
- 组合和重用
- 在普通代码和测试中使用
- 收藏
- 在模拟框架中使用
- 可以使用一般谓词函数
- 非常好的日志能力
- 可与其他匹配器结合,描述和故障描述准确准确
Cons:
缺点:
- Well it's pretty obvious right? This is way more verbose than assert or junitx (for this particular case)
- You'll probably need to include the hamcrest libs to get the most benefit
- 嗯,这很明显吧?这比 assert 或 junitx 更冗长(对于这种特殊情况)
- 您可能需要包含 hamcrest 库才能获得最大收益
回答by Jonik
Here's one simple approach for checking if the files are exactlythe same:
这是检查文件是否完全相同的一种简单方法:
assertEquals("The files differ!",
FileUtils.readFileToString(file1, "utf-8"),
FileUtils.readFileToString(file2, "utf-8"));
Where file1and file2are Fileinstances, and FileUtilsis from Apache Commons IO.
Wherefile1和file2areFile实例,FileUtils来自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.
没有多少自己的代码需要你维护,这总是一个加分项。:) 如果您已经在您的项目中使用了 Apache Commons,则非常容易。但是没有像mark 的解决方案那样好的、详细的错误消息。
Edit:
Heh, looking closer at the FileUtilsAPI, there's an even simpler way:
编辑:
嘿,仔细看看FileUtilsAPI,还有一种更简单的方法:
assertTrue("The files differ!", FileUtils.contentEquals(file1, file2));
As a bonus, this version works for all files, not just text.
作为奖励,此版本适用于所有文件,而不仅仅是文本。
回答by Scott Langley
Here is a more exhaustive list of File comparator's in various 3rd-party Java libraries:
以下是各种 3rd-party Java 库中文件比较器的更详尽列表:
回答by Mookie Wilson
FileUtilssure is a good one. Here's yet another simple approachfor checking if the files are exactly the same.
FileUtils肯定是个好的。这是检查文件是否完全相同的另一种简单方法。
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.
虽然 assertEquals() 确实比 assertTrue() 提供了更多的反馈,但 checksumCRC32() 的结果很长。所以,这可能没有内在的帮助。
回答by Bogdan Calmac
As of 2015, I would recomment AssertJ, an elegant and comprehensive assertion library. For files, you can assert against another file:
到 2015 年为止,我会推荐AssertJ,这是一个优雅而全面的断言库。对于文件,您可以针对另一个文件进行断言:
@Test
public void file() {
File actualFile = new File("actual.txt");
File expectedFile = new File("expected.txt");
assertThat(actualFile).hasSameContentAs(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
回答by Mauricio Gracia Gutierrez
This is my own implementation of equalFiles, no need to add any library to your project.
这是我自己的 实现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;
}
And to use it just use regular AssertTrueJUnit method
并使用它只需使用常规的AssertTrueJUnit 方法
assertTrue(equalFiles(expected, output)) ;
回答by Jonathan Andersson
Simple comparison of the content of two files with java.nio.fileAPI.
用java.nio.fileAPI简单比较两个文件的内容。
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));
}

