我试图在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:预期:欢迎来到宏 计算应用实际:
我不知道问题是什么。
答案 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));