title: Mockito fails to verify multiple invocations of methods from org.slf4j.Logger
body: <p><strong>I have a method that contains 2 conditions. In each condition the Logger.error method is invoked. The first test, that verifies the invocation of that method, succeeds, but any other test fails with</strong> </p>
  
  <blockquote>
    <p>Wanted but not invoked...Actually, there were zero interactions with
    this mock.</p>
  </blockquote>
  
  <p><strong>Does anyone know why this happens?</strong>  </p>
  
  <p>Below, I provided an example class and a unit test that will generate the issue:</p>
  
  <pre><code>package packageName;
  
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  public class X {
  
      private static final Logger LOGGER = LoggerFactory.getLogger(X.class);
  
      public void execute(boolean handle1stCase) {
          if (handle1stCase) {
              LOGGER.error("rumpampam");
          } else {
              LOGGER.error("latida");
          }
      }
  }
  </code></pre>
  
  <p>The test:</p>
  
  <pre><code>package packageName;
  
  import org.apache.commons.logging.LogFactory;
  import org.junit.Before;
  import org.junit.Test;
  import org.junit.runner.RunWith;
  import org.mockito.Mock;
  import org.mockito.MockitoAnnotations;
  import org.powermock.api.mockito.PowerMockito;
  import org.powermock.core.classloader.annotations.PrepareForTest;
  import org.powermock.modules.junit4.PowerMockRunner;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  import static org.mockito.Matchers.any;
  import static org.mockito.Mockito.*;
  import static org.powermock.api.mockito.PowerMockito.mockStatic;
  
  @RunWith(PowerMockRunner.class)
  @PrepareForTest({LoggerFactory.class})
  public class XTest {
  
      @Mock
      private Logger loggerMock;
  
      private X x;
  
      @Before
      public void construct() {
          MockitoAnnotations.initMocks(this);
  
          mockStatic(LoggerFactory.class);
          when(LoggerFactory.getLogger(any(Class.class))).thenReturn(loggerMock);
  
          x = new X();
      }
  
      @Test
      public void whenFirstCaseErrorLogged() throws Exception {
          x.execute(true);
          verify(loggerMock, times(1)).error("rumpampam");
      }
  
      @Test
      public void whenSecondCaseErrorLogged() throws Exception {
          x.execute(false);
          verify(loggerMock, times(1)).error("latida");
      }
  }
  </code></pre>
  
  <p>The outcome:</p>
  
  <blockquote>
    <p>Wanted but not invoked: loggerMock.error("latida");
    -> at packageName.XTest.whenSecondCaseErrorLogged(XTest.java:51)<br>
    Actually, there were zero interactions with this mock.</p>
  </blockquote>
  
  <p><strong>EDIT:</strong><br>
  I gave my short answer of why the every test except the 1st was failing in a <a href="https://stackoverflow.com/a/20196591/521754">comment of this answer</a>. </p>
  
  <p><strong>MY SOLUTION TO THE PROBLEM</strong>:<br>
  In the test provide a:  </p>
  
  <pre><code>public static Logger loggerMockStatic;  
  </code></pre>
  
  <p>Than create only one instance for all the tests and provide it in the static variable, and use the static loggerMockStatic from than on. So you would have:  </p>
  
  <pre><code>    ...  
      MockitoAnnotations.initMocks(this);
  
      if (loggerMockStatic == null) {
          loggerMockStatic = loggerMock;
      }
  
      mockStatic(LoggerFactory.class);
      //when(LoggerFactory.getLogger(any(Class.class))).thenReturn(loggerMock);
      when(LoggerFactory.getLogger(any(Class.class))).thenReturn(loggerMockStatic);
      ...
  </code></pre>
  
  <p>and use loggerMockStatic in the verify methods instead of loggerMock.</p>
  
  <p><strong>SOME THOUGHTS REGARDING APPROACH</strong>:<br>
  For me this is good because<br>
  1. it doesn't break design (if you considered that the needed variable should have been a constant, than it will stay this way).<br>
  2. its only 4 lines added in the test that will allow you to test the constant (in this case logger) behavior. Not much polluting and test case is still clear.</p>
  
  <p>The "delete final and provide setter" approach as I explained in <a href="https://stackoverflow.com/a/20198872/521754">this answer</a> opens the system to vulnerabilities. There is no need for someone to set the logger to the class, and I would always like the system to be as opened as needed. Providing a setter only for the need of a test is not desired. The test should work for the implementation, not the other way around.</p>
  
  <p>Specifically on testing the logging, I don't consider that logging should be tested in general (most of the) cases. Logging should be an aspect of the application. And when you have other outputs to test for a certain path, than those outputs should be tested. But in this case (and maybe others) where there is no other output for a certain path, like logging and returning on a certain condition, testing the log (according to me) is needed. I want to always know that the log message will remain being logged even if someone changes the condition. If there was no log, and if someone changes the condition the wrong way there will be no way of knowing that the mistake resides in this piece of code (except maybe with debugging).</p>
  
  <p>I was discussing with some colleagues that having a separate class for doing the logging would do the trick. That way the constant is isolated in another class, and you will be able to check the behavior with only Mockito. They made a further remark that this way if you would wanted to send the log to an email it would be easier to change.<br>
  First of all, I consider this a premature modularization IF you are not aiming in near future to switch between logging ways.<br>
  Secondly, using only Mockito + having another class and + 3 lines of code VS my one line of code (logger.error(...)) + using PowerMockito, I would again use the later. Adding additional dependencies during testing will not make you production code slower and bulkier. Perhaps when considering continues integration and that testing is also as important as other phases, you might say that this will make the process slower and bulkier while testing, but I would sacrifice that - it seems not too big of deal to me.</p>