JUnit ByteArrayOutputStream问题

时间:2015-11-17 13:39:11

标签: java junit

我试图在JUnit中进行测试,我想测试控制台是否打印出我想要打印的消息。代码如下所示:

public class MainTestingClass extends TestCase {

    private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();

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

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

    @Test
    public void testPracticalViewConsole() {
        PracticalView view = new PracticalView();
        view.PrintResults();
        assertEquals("welcome to the macro counting app", outContent.toString());
    }
}

但由于某种原因,system.out仍会打印到控制台,在测试中我得到:

  

junit.framework.ComparisonFailure:预期:欢迎来到宏   计算应用实际:

我不知道问题是什么。

2 个答案:

答案 0 :(得分:3)

System类进行交互是一个非常难看的解决方案,更不用说System.setOut(null)可能会产生副作用(例如,您将无法在此JVM的控制台中看到更多内容)。我不确定它是如何工作的,因为该方法是原生的,而它的javadoc是模糊的。

测试中的一个好习惯是将代码与您无法控制的代码隔离(此处为System类)。你应该将System.out.println包装到你自己的类中:

public class Printer {

    public void println(Object object) {
        System.out.println(object);
    }

}

然后你可以使用一个模拟框架(这里:mockito)来模拟Printer,对依赖注入和断言进行交互:

@Test
public void testPracticalViewConsole(){
    Printer printer = mock(Printer.class);
    PracticalView view = new PracticalView(printer);

    view.PrintResults();

    verify(printer, times(1)).println("welcome to the macro counting app");
}

修改

为了帮助您开始使用mockito,以下是您需要的单个maven依赖项:

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>1.10.19</version>
</dependency>

这些是上述测试的导入:

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

答案 1 :(得分:3)

我已经复制了你的实验,而且我从经验上发现这种奇怪的行为的原因是超类TestCase (这甚至不是必需的,因为你正在使用JUNIT 4注释)。放下它,看看它是如何工作的。

并且,尽管并非绝对必要,但如果使用autoFlush = true实例化PrintStream将会更安全:

System.setOut(new PrintStream(outContent, true));