Java:使用 assertEquals 测试系统输出,包括 "new lines"

标签 java unit-testing junit

我目前正在为策略设计模式编写单元测试。我正在将系统输出与 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());
    }
}

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

Quack
I'm flying!!
I can't fly
I'm flying with a rocket

编辑:

最快的解决方案似乎是在我的“\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());

另外:我忘了说大部分代码都来自 Eric Freeman、Elisabeth Robson、Bert Bates 和 Kathy Sierra 合着的“Head First Design Patterns”一书。

最佳答案

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

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

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

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

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

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

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

然后如果测试失败你可以给出更好的问题描述。例如

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

会输出

org.junit.ComparisonFailure: Line 2 
Expected :I can not fly
Actual   :I can't fly

关于Java:使用 assertEquals 测试系统输出,包括 "new lines",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41674408/

相关文章:

java - 如何将 jFrame 添加到 Netbeans 中的主类中?

java - AppEngine 开发服务器 - 并发任务限制

java - 为 XPath 评估设置当前节点

c# - 如何对模板10的RaisePropertyChanged进行单元测试?

unit-testing - 使用自定义属性编辑器时如何对 Grails Controller 进行单元测试?

unit-testing - 将特定测试编译成二进制文件

java - Java中有向图的实现

Java-Junit/Junit方法的误解

java - JUnit 测试结果在测试失败时显示 0,但在测试正常时显示 1

java - Mockito 在同一个 NavigationSet 上提供无限 while 循环和有限 for 循环