Java:测试系统输出,包括带有assertEquals的"新行"

Wou*_*rck 6 java junit unit-testing

我目前正在为战略设计模式编写单元测试.我正在将系统输出与assertEquals方法中的字符串进行比较.输出看起来相同但我的测试仍然失败... 我在想我忘记了与新线或标签有关的事情?

我的单元测试:

import static org.junit.Assert.*;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class MiniDuck1Test {

    private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
    private final ByteArrayOutputStream errContent = new ByteArrayOutputStream();

    @Before
    public void setUpStreams() {
        System.setOut(new PrintStream(outContent));
        System.setErr(new PrintStream(errContent));
    }

    @After
    public void cleanUpStreams() {
        System.setOut(null);
        System.setErr(null);
    }

    @Test
    public void testDuck1() {       
        Duck mallard = new MallardDuck();
        mallard.performQuack();
        mallard.performFly();

        Duck model = new ModelDuck();
        model.performFly();
        model.setFlyBehavior(new FlyRocketPowered());
        model.performFly();

        assertEquals("Quack\nI'm flying!!\nI can't fly\nI'm flying with a rocket", outContent.toString().trim());
    }
}
Run Code Online (Sandbox Code Playgroud)

输出(第二行和第三行显示为红色):

Quack
I'm flying!!
I can't fly
I'm flying with a rocket
Run Code Online (Sandbox Code Playgroud)

编辑:

最快的解决方案似乎是在我的"\n"前添加一个"\ r".多个答案告诉我,这需要在Windows上完成.应用此之后,我的assertEquals看起来像:

assertEquals("Quack\r\nI'm flying!!\r\nI can't fly\r\nI'm flying with a rocket", outContent.toString().trim());
Run Code Online (Sandbox Code Playgroud)

另外:我忘了提到大部分代码都来自于Eric Freeman,Elisabeth Robson,Bert Bates和Kathy Sierra的书"Head First Design Patterns".

Ren*_*ink 11

除了其他答案之外,如果您正在寻找一种独立于平台的方式......

一个快速的独立于平台的解决方案可以是替换行分隔符

String expected = "Quack\nI'm flying!!\nI can't fly\nI'm flying with a rocket"
                       .replaceAll("\\n|\\r\\n", System.getProperty("line.separator"));
assertEquals(expected, outContent.toString().trim());
Run Code Online (Sandbox Code Playgroud)

或使用 aPrintWriter构建预期的字符串。

StringWriter expectedStringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(expectedStringWriter);

printWriter.println("Quack");
printWriter.println("I'm flying!!");
printWriter.println("I can't fly");
printWriter.println("I'm flying with a rocket");
printWriter.close();

String expected = expectedStringWriter.toString();
assertEquals(expected, outContent.toString());
Run Code Online (Sandbox Code Playgroud)

或者创建一个自己的断言类来重用它

class MyAssert {

    public static void assertLinesEqual(String expectedString, String actualString){
        BufferedReader expectedLinesReader = new BufferedReader(new StringReader(expectedString));
        BufferedReader actualLinesReader = new BufferedReader(new StringReader(actualString));

        try {
            int lineNumber = 0;

            String actualLine;
            while((actualLine = actualLinesReader.readLine()) != null){
                String expectedLine = expectedLinesReader.readLine();
                Assert.assertEquals("Line " + lineNumber, expectedLine, actualLine);
                lineNumber++;
            }

            if(expectedLinesReader.readLine() != null){
                Assert.fail("Actual string does not contain all expected lines");
            }
        } catch (IOException e) {
            Assert.fail(e.getMessage());
        } finally {
            try {
                expectedLinesReader.close();
            } catch (IOException e) {
                Assert.fail(e.getMessage());
            }
            try {
                actualLinesReader.close();
            } catch (IOException e) {
                Assert.fail(e.getMessage());
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果测试失败,您可以给出更好的问题描述。例如

MyAssert.assertLinesEqual(
         "Quack\nI'm flying!!\nI can not fly\nI'm flying with a rocket\n",
         outContent.toString());
Run Code Online (Sandbox Code Playgroud)

会输出

org.junit.ComparisonFailure: Line 2 
Expected :I can not fly
Actual   :I can't fly
Run Code Online (Sandbox Code Playgroud)