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 file1
and file2
are File
instances, and FileUtils
is from Apache Commons IO.
Wherefile1
和file2
areFile
实例,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 FileUtils
API, there's an even simpler way:
编辑:
嘿,仔细看看FileUtils
API,还有一种更简单的方法:
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
FileUtils
sure 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 AssertTrue
JUnit method
并使用它只需使用常规的AssertTrue
JUnit 方法
assertTrue(equalFiles(expected, output)) ;
回答by Jonathan Andersson
Simple comparison of the content of two files with java.nio.file
API.
用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));
}