Q:

How to mock an interface default method Java8/Mockito2

I cannot mock a method defined as default in an interface. Can anyone help me here?
The interface has default method providing a logger.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public interface Loggable {

  default Logger logger() {
    return LoggerFactory.getLogger(this.getClass());
  }
}

It is used this way:
public class AppShowOff implements Loggable{

  public void doMagic() {
    logger().debug("It works");
    System.out.println("Works");
  }
}

now I would like to write a test proving that debug method has been called.
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import org.junit.Test;
import org.mockito.Mockito;
import org.slf4j.Logger;

public class AppShowOffTest {

  @Test
  public void doMagic() {
    Logger loggerMock = mock(Logger.class);
    Loggable loggableMock = mock(Loggable.class); // <- not needed, but I also tried this way

    // mocks done

    AppShowOff app = new AppShowOff();
    AppShowOff appSpy = Mockito.spy(new AppShowOff());

    when(loggableMock.logger()).thenReturn(loggerMock);
    when(appSpy.logger()).thenReturn(loggerMock);

    app.doMagic();
    verify(loggerMock, times(1)).debug(any());
  }
}

as you can see I have tried to mock the default method in two ways: 
when(loggableMock.logger()).thenReturn(loggerMock);
when(appSpy.logger()).thenReturn(loggerMock);

but it does not work. The result is:

Wanted but not invoked: logger.debug();
  -> at so.AppShowOffTest.doMagic(AppShowOffTest.java:29) Actually, there were zero interactions with this mock.

A:

Here:
AppShowOff app = new AppShowOff();
AppShowOff appSpy = Mockito.spy(new AppShowOff());

That first app ... is never used, besides to call your method under test doMagic().
The simple answer: drop app completely, and invoke appSpy.doMagic().

