将文本文件与 Junit 进行比较

发布于 2024-07-12 09:56:03 字数 480 浏览 4 评论 0 原文

我正在使用 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());
}

这是比较文本文件的好方法吗? 什么是首选?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

十年九夏 2024-07-19 09:56:03

这是检查文件是否完全相同的一种简单方法:

assertEquals("The files differ!", 
    FileUtils.readFileToString(file1, "utf-8"), 
    FileUtils.readFileToString(file2, "utf-8"));

其中 file1file2File 实例,和 FileUtils 来自 Apache Commons IO

没有太多自己的代码需要维护,这始终是一个优点。 :) 如果您已经在项目中使用了 Apache Commons,那么非常简单。 但没有像 mark 的解决方案中那样的详细错误消息。

编辑
呵呵,仔细观察 FileUtils API,甚至还有一个 更简单的方法

assertTrue("The files differ!", FileUtils.contentEquals(file1, file2));

作为奖励,此版本适用于所有文件,而不仅仅是文本。

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.

浮生面具三千个 2024-07-19 09:56:03

junit-addons 对此有很好的支持:FileAssert

它为您提供了如下例外:

junitx.framework.ComparisonFailure: aa Line [3] expected: [b] but was:[a]

junit-addons has nice support for it: FileAssert

It gives you exceptions like:

junitx.framework.ComparisonFailure: aa Line [3] expected: [b] but was:[a]
冷月断魂刀 2024-07-19 09:56:03

截至 2015 年,我会推荐 AssertJ,一个优雅而全面的断言库。 对于文件,您可以针对另一个文件进行断言:

@Test
public void file() {
    File actualFile = new File("actual.txt");
    File expectedFile = new File("expected.txt");
    assertThat(actualFile).hasSameTextualContentAs(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

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
暮凉 2024-07-19 09:56:03

使用 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);

或者,如果您想比较各个行:

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));
}

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));
}
萌化 2024-07-19 09:56:03

我建议使用 Assert.assertThat 和 hamcrest 匹配器(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;
         }
      }
   }
}

匹配器优点:

  • 组合和重用
  • 在正常代码以及测试中使用
    • 收藏
    • 用于模拟框架
    • 可以使用通用谓词函数
  • 非常好的日志能力
  • 可以与其他匹配器结合使用,并且描述和失败描述准确且精确

缺点:

  • 嗯,这很明显,对吧? 这比断言或 junitx 更详细(对于这种特殊情况)
  • 您可能需要包含 hamcrest 库才能获得最大好处

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:

  • 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
み青杉依旧 2024-07-19 09:56:03

FileUtils 确实是一个不错的选择。 这是另一个 检查文件是否完全相同的简单方法

assertEquals(FileUtils.checksumCRC32(file1), FileUtils.checksumCRC32(file2));

虽然assertEquals()确实比assertTrue()提供了更多的反馈,但checksumCRC32()的结果很长。 所以,这可能没有什么本质上的帮助。

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.

七禾 2024-07-19 09:56:03

如果预期的行数比实际的行数多,则在稍后进入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());
}

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());
}
千寻… 2024-07-19 09:56:03

这是我自己的 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)) ;

This is my own implementation of equalFiles, no need to add any library to your project.

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(equalFiles(expected, output)) ;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文