0

I have a logger using java api, and in the unit test I set the output from the standard to my output and check if the messages are being printed(log, exceptions etc...) my code is

    ByteArrayOutputStream mockedOutput = new ByteArrayOutputStream();
    System.setOut(new PrintStream(mockedOutput));
    System.setErr(new PrintStream(mockedOutput));

but the log is not being captured in the output, if I check the console(eclipse, or running through maven) the log is there meaning the is not going through my output. If replace the log for system.out.print then it works, I also can see exceptions and so on, only things that are being logged using java API is not being captured in the mockedOutput.

Does anyone have an idea?, I am running out of clue.

  • Why do you test on `System.out` and `System.err`? I would recommend to rewrite the code under test so that a logger is injected and then mock the logger. – Turing85 Feb 01 '20 at 22:12
  • How are you reading bytes into the ByteArrayOutputStream instance? – Adrian M. Feb 01 '20 at 22:27
  • @Turing85 the important is the System.err I just added System.out to make sure that was not going through the System.out. Inject would be nice, but I cannot at this moment – Claudio Resende Feb 01 '20 at 22:35
  • As I said: I would refactor the code to inject the logger, inject a mocked logger and then verify calls on the mock. – Turing85 Feb 01 '20 at 22:37
  • @AdrianM. String outputString = new String(mockedOutput.toByteArray()); I had done that in other project and it worked – Claudio Resende Feb 01 '20 at 22:37
  • @Turing85, at the moment I cannot refactor the project. regardless of the approach, I should be able to retrieve the output in my ByteArrayOutputStream – Claudio Resende Feb 01 '20 at 22:40
  • @ClaudioResende, I see the bytearraystream's bytearray getting passed to the String constructor, but was asking about how data is getting to the outputstream itself. If there's nothing in the stream to output, nothing would get logged. – Adrian M. Feb 01 '20 at 22:40
  • @AdrianM. that's the point, the data is not getting in the outputstream, although I can see in the console. and is being used simple java.util.logging.Logger.severe(message); – Claudio Resende Feb 01 '20 at 22:43
  • @ClaudioResende, it seems there's no connection between the logger and the outputstream. The system configuration looks to be more or less parallel to the logger in a sense. Is there a Logger method that would let you set the output to the baos? – Adrian M. Feb 01 '20 at 22:46
  • @AdrianM. I did not find any, but a strange thing is... if I set the output in a static scope it works running only one test, the log goes through the mockedOutput, but if I run the whole set of a test does not work. – Claudio Resende Feb 01 '20 at 22:52
  • It may be related to how the default logger setup. Perhaps the following question would help you orient to what's required to override this default behavior: https://stackoverflow.com/questions/2533227/how-can-i-disable-the-default-console-handler-while-using-the-java-logging-api/2533250#2533250 – Adrian M. Feb 01 '20 at 22:56
  • 1
    @AdrianM. for sure the problem is the logger setup, the question did not come, but I will check the api documentation, thank you anyway. – Claudio Resende Feb 01 '20 at 22:58

1 Answers1

0

Include more of your code and logging.properties file because the output depends on when your loggers and therefore handlers are created.

If you are relying on the ConsoleHandler to write to your stream then you have to delay the creation of your logger. This is because the ConsoleHandler will capture a snapshot of System.err.

Without seeing your code you need to ensure that:

  1. You have delayed the creation of your ConsoleHandler until you have remapped System.err.
  2. If you are depending on the root logger then delay the construction of the root logger util you have remapped System.err. This is done by calling Logger.getLogger("") after remapping of System.err.
  3. Don't let your loggers get garbage collected unexpectedly.
jmehrens
  • 10,580
  • 1
  • 38
  • 47