1

我有一个应用程序,我想编写单元测试来测试输出,写入 System.out(可能还有 System.err)。每个单独的测试都按预期工作,但是当在同一个类中添加多个测试时,一些测试会失败,因为 JUnit4 似乎是多线程的(因此不能保证何时确切地重置流)。当我在自己的类中分离所有测试方法并使用测试套件时,也会发生同样的情况。

有任何想法吗?

private static final PrintStream SYS_OUT = System.out;
private static final PrintStream SYS_ERR = System.err;

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

@Before
public final void setUpStreams() throws UnsupportedEncodingException {
    System.setOut(new PrintStream(this.outContent, true, CHARSET));
    System.setErr(new PrintStream(this.errContent, true, CHARSET));
}

@After
public final void cleanUpStreams() {
    System.setOut(SYS_OUT);
    System.setErr(SYS_ERR);
}

@Test
public final void listServicesAndMethods() throws ServiceException, UnsupportedEncodingException {
    com.example.Main.main(new String[]{"--list-services"});
    LOG.debug(this.outContent.toString(CHARSET));
    assertTrue("String not found", this.outContent.toString(CHARSET).contains("Some string"));
    assertFalse("Other string found", this.outContent.toString(CHARSET).contains("Some other string"));
    this.outContent.reset();
    this.errContent.reset();
}

编辑:事实证明,测试失败的问题不是(只是?)因为流,而是因为我将选项存储在我的主类的静态字段中。这具有在连续测试期间几个选项保持活动的效果。我意识到,在实现了 Arian 的建议之后,我使用第二个类作为实例,而不是调用静态方法,从而解决了我的问题。

感谢所有回复的人。

4

1 回答 1

0

如果尚未这样做,请重写应用程序的部分以将输出作为参数,而不是直接写入System.out. 无论测试如何,这通常都是更好的设计。

在每个测试中,创建一个的输出流(如果必须的话,也可以监视System.out)并将其传递给被测代码单元。

于 2013-01-04T10:33:52.053 回答