I've been working with JMockit and its admittedly steep learning curve. I'm pretty new with mocking in general so please excuse the ignorance.
I'm trying to mock out the Logger interface so that I can verify the catch statement is working correctly. Call this an exercise in understanding how JMockit works. The implementing class for the Logger interface is Log4jLoggerAdapter so I thought if I passed an instance of that into my Expectations() block, JMockit would use dynamic partial mocking and "see" my logger statement. Instead, I get the following error:
mockit.internal.MissingInvocation: Missing invocation of: org.slf4j.impl.Log4jLoggerAdapter#error(String msg, Throwable t)
The Class Being Tested
public class MyLoggedClass {
private static final Logger LOGGER = LoggerFactory.getLogger(MyLoggedClass.class);
... // Other variables
@Override
public void connect() {
String info = getServiceInfo();
try {
connector = MyConnectionFactory.connect(info);
} catch (Exception e) {
LOGGER.error("Exception connecting to your service with: " + info, e);
}
}
... // Other methods
}
My @Test
public class MyLoggedClassTest {
@Tested
MyLoggedClass myLoggedClass;
@Test
public void myLoggingTest(@Mocked final Log4jLoggerAdapter logger){
new Expectations(MyConnectionFactory.class, logger){{
MyConnectionFactory.connect(anyString);
result = new Exception();
logger.error(anyString, (Throwable)any);
}};
myLoggedClass.connect();
}
I'd detail the other approaches I've tried but this page would turn into a book. This is my best approach. Any ideas?
* Update * (yes, that was quick)
I changed @Mocked to @Cascading and removed the logger field from my Expectations signature and it worked. I don't understand why. Can someone please provide an explanation? Fumbling about until you stumble on something that works but you don't understand is not a recipe for success. See below:
@Test
public void myLoggingTest(@Cascading final Log4jLoggerAdapter logger){
new Expectations(MyConnectionFactory.class){{
MyConnectionFactory.connect(anyString);
result = new Exception();
logger.error(anyString, (Throwable)any);
}};
myLoggedClass.connect();
}