Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using JMockit to mock autowired interface implementations

We are writing JUnit tests for a class that uses Spring autowiring to inject a dependency which is some instance of an interface. Since the class under test never explicitly instantiates the dependency or has it passed in a constructor, it appears that JMockit doesn't feel obligated to instantiate it either.

Up until now we have been using SpringRunner to have Spring load mock dependencies for us, which works. Two things we don't like about this are 1) the Spring framework has to be loaded and initialized each time running the tests which is not exactly speedy, and 2) we are forced to explicitly create all mock dependencies as real classes, something which JMockit helps eliminate.

Here's a simplified example of what we're testing:

public class UnitUnderTest {

   @Autowired
   ISomeInterface someInterface;

   public void callInterfaceMethod() {

      System.out.println( "UnitUnderTest.callInterfaceMethod calling someInterface.doSomething");
      someInterface.doSomething();
   }

}

So, the question is, is there a way to have JMockit create a mock someInterface?

like image 951
SwimsZoots Avatar asked Dec 30 '09 15:12

SwimsZoots


1 Answers

If you have a @Qualifier annotation for the interface, you need to name your @Injectable field exactly as it is named in qualifier.

Here is quote from JMockit doc:

Custom names specified in field annotations from Java EE (@Resource(name), @Named) or the Spring framework (@Qualifier) are used when looking for a matching @Injectable or @Tested value. When such a name contains a - (dash) or . (dot) character, the corresponding camel-cased name is used instead.

For example:

@Component
public class AClass {

   @Autowired
   private Bean1 bean1;

   @Autowired
   @Qualifier("my-dashed-name")
   private AmqpTemplate rpcTemplate;
}

Unit test class:

public class AClassTest {

   @Injectable
   private Bean1 bean1;

   @Injectable
   private AmqpTemplate myDashedName;

   @Tested
   private AClass aClass = new AClass();
}

Also there is no need to use setFiled for each @Autowired bean, all fields injects automatically when @Tested class instantiated. Tested on JMockit ver. 1.30

like image 182
Denis Makarskiy Avatar answered Oct 06 '22 01:10

Denis Makarskiy