문제

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

이것이 텍스트 파일을 비교하는 좋은 방법입니까? 선호되는 것은 무엇입니까?

도움이 되었습니까?

해결책

주니트 아들 그것에 대한 훌륭한 지원이 있습니다 : Fileassert

그것은 당신에게 다음과 같은 예외를 제공합니다.

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

다른 팁

파일이 있는지 확인하기위한 간단한 접근법은 다음과 같습니다. 바로 그거죠 똑같다:

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

어디에 file1 그리고 file2 ~이다 File 인스턴스 및 FileUtils 출신입니다 아파치 커먼즈 IO.

당신이 유지 관리 할 자신의 코드는 많지 않습니다. 이것은 항상 플러스입니다. :) 그리고 이미 프로젝트에서 Apache Commons를 사용하고 있다면 매우 쉽습니다. 그러나 IN과 같은 멋지고 상세한 오류 메시지는 없습니다 마크의 해결책.

편집하다:
heh, 더 자세히 바라본다 FileUtils API, 짝수가 있습니다 더 간단한 방법:

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

보너스 로이 버전은 텍스트뿐만 아니라 모든 파일에 대해 작동합니다.

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

assert.assertthat and a를 사용하는 것이 좋습니다 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;
         }
      }
   }
}

경기자 장점 :

  • 구성과 재사용
  • 테스트뿐만 아니라 일반 코드로 사용하십시오
    • 컬렉션
    • 모의 프레임 워크에서 사용
    • 일반적인 술어 기능을 사용할 수 있습니다
  • 정말 좋은 로그 가능성
  • 다른 매칭 자와 결합 할 수 있으며 설명 및 실패 설명은 정확하고 정확합니다.

단점 :

  • 꽤 분명해? 이것은 Assert 또는 Junitx보다 더 장점입니다 (이 특별한 경우)
  • 가장 큰 혜택을 얻으려면 Hamcrest Libs를 포함해야 할 것입니다.

FileUtils 물론 좋은 것입니다. 여기에 또 다른 것이 있습니다 간단한 접근 파일이 정확히 동일한 지 확인합니다.

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

Assertequals ()는 AssertTrue ()보다 약간 더 많은 피드백을 제공하지만 checksumcrc32 ()의 결과는 길다. 따라서 그것은 적절하게 도움이되지 않을 수 있습니다.

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

예상이 실제보다 더 많은 줄이 있다면 나중에 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());
}

이것은 내 자신의 구현입니다 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 주니트 방법

assertTrue(equalFiles(expected, output)) ;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top