What are Mockito Extra Interfaces?

Mockito is my favored little helper if it comes down to write light weight JUnit tests. It is very useful to replace the ‘real’ dependencies of a unit under test easily by mocks if necessary. In particular when working on the borderline to framework APIs such dependencies can otherwise be very expensive to setup.

But sometimes the situation is a bit more complicated. E.g. if the test needs to interact for some reason at least with one real instance that belongs to such a framework. If this interaction includes passing a mock as parameter to this instance, on hard luck the implementation casts the parameter to a type that is unknown from the interactor’s point of view.

 
Here is a simple example to clarify this:

public interface Foo {
  [...]
}

public class Bar {

  public Bar( Foo foo ) {
    Runnable runnable = ( Runnable )foo;
    runnable.run();
  }

  [...]
}

public class SomeTest {

  @Test
  public void testConstructor() {
    Foo fooMock = mock( Foo.class );

    // fails with ClassCastException
    Bar bar = new Bar( fooMock );

    [...]
  }
}

Think of the class Bar as framework code that expects a certain kind of implementation. As the parameter type Foo does not reflect this expectation passing a mock of Foo to the constructor of Bar will cause the test to fail with a ClassCastException.

Maybe the first thought that comes to your mind when looking at the situation above is that the framework sucks by casting to an undeclared type and that one is better off by throwing everything away and starting all over again!

Unfortunately there are real world situations where such a behavior is arguably valid. The Eclipse platform for example has a lot of interfaces that are declared as ‘not intended to be implemented by clients’. A good example for this is the IHistoryView interface of the team API. Working with the 3.x platform one can be pretty sure that the IHistoryView implementation extends IViewPart, although this is a detail that is not exposed by the history view interface.

Given this circumstances, occasionally it might be desirable to create a mock of multiple types – a mock that implements IHistoryView and IViewPart – although the API does not indicate all of them. Mockito facilitates this via the lesser-known MockSettings#extraInterfaces mock configuration capability. The following snippet shows how to use extraInterfaces to fix the test of the example above.

@Test
public void testConstructor() {
  Foo mock = mock( Foo.class,
                   withSettings().extraInterfaces( Runnable.class ) );

  // the mock now supports the cast to runnable
  Bar bar = new Bar( mock );

  [...]
}

The method call withSettings creates a new instance of MockSettings that gets configured with the additional Runnable type. The generated Foo mock instance implements both Foo and Runnable. And now the test passes.

However keep in mind that although the motivation for the usage of extra interfaces in this post might seem plausible, it cannot be stressed enough that you should really consider twice before actually using this feature. Or as the documentation states ‘If you happen to use it often than please make sure you are really producing simple, clean & readable code.’ And carelessly used it is definitely a predetermined breaking point.

Reference: What are Mockito Extra Interfaces? from our JCG partner Frank Appel at the Code Affine blog.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

Leave a Reply


× six = 18



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close