问题
I am working with some legacy code that has some System.out.print
commands in itself.
My eCobertura plugin shows this lines red, so I want to unit test them.
Here in stackoverflow I found a way to unit test console outputs which i thing is very interesting.
This is how I do it:
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 out() {
System.out.print("Some message from the system");
assertEquals("Some message from the system", outContent.toString());
}
So far so good, the test goes green but when I run the code coverage plugin again, I get this message:
Exception in thread "Thread-0" java.lang.NullPointerException at net.sourceforge.cobertura.coveragedata.TouchCollector.applyTouchesOnProjectData(TouchCollector.java:186) at net.sourceforge.cobertura.coveragedata.ProjectData.saveGlobalProjectData(ProjectData.java:267) at net.sourceforge.cobertura.coveragedata.SaveTimer.run(SaveTimer.java:31) at java.lang.Thread.run(Thread.java:662)
I have some doubts:
- Is it correct to try to unit test
System.out.print()'s
? - Is eCoberturaincompatible with this type of test?
- If eCobertura is not compatible with this type of test, why does it show the line red?
- Is there something wrong in my test?
- I am using jUnit 4.11 do you think this has something to do with it?
- why is eCobertura giving me this error?
回答1:
Is it correct to try to unit test System.out.print()'s?
This highly depends on what you are trying to test. I don't think it is necessary to test System.out.print() itself, I hope Sun/Oracle has done this enough. But if your application outputs important information to the console and this is your only way to validate the output, than yes, you need to test it. If you can test your code by testing the corresponding classes, then you probably don't need to test the output stream itself.
Look at databases, for example: I don't test the JDBC driver it self, but I do test all code/functionality that is part of loading/saveing data from and to the database.
The red line only means the code line was never executed. This can be okay or it could mean that your tests don't touch a part of your code that they should. Getting test coverage high is important, but aiming for 100% might not always be necessary (think Pareto principle)
As for your Null Pointer Exception
Your call to System.setOut(null);
set the System.out to null and eCobertura probably tries to write something to Standard Out, which is null now. You might need to save the orignial Out Stream in your @Before Method and restore it in our @After method to allow the code that follows to use StdOut
Is eCobertura incompatible with this type of test?
If eCobertura is not compatible with this type of test, why does it show the line red?
why is eCobertura giving me this error?
It could be that the communication between eclipse and eCobertura happens via Standard Out, but I am not sure. If this is the case, than if you redirect Standard Out not only your output but also the output from Cobertura gets redirected and the GUI does not see anymore what gets executed and what not, thus coloring it red
Is there something wrong in my test?
It might be necessary to ensure StdOut is correctly restored.
I am using jUnit 4.11 do you think this has something to do with it?
No, I don't think so
回答2:
If it's correct to use System.out.println's in your code, then it's correct to (unit/integration) test them.
There is a useful System test utility called System Rules for testing this kind of code.
http://stefanbirkner.github.com/system-rules/
来源:https://stackoverflow.com/questions/15175175/should-we-unit-test-console-outputs