Tag Archives: Spring

Use Mockito to mock autowired fields

EDIT: Field injections are widely considered (including myself) as bad practice. Read here for more info. I would suggest to use constructor injection instead.

Dependency injection is very powerful feature of Inversion of Control containers like Spring and EJB. It is always good idea to encapsulate injected values into private fields. But encapsulation of autowired fields decreases testability.

I like the way how Mockito solved this problem  to mock autowired fields. Will explain it on example. (This blog post expects that you are little bit familiar with Mockito syntax, but it is self-descriptive enough though.)

Here is first dependency of testing module. It is Spring singleton bean. This class will be mocked in the test.

@Repository
public class OrderDao {
	public Order getOrder(int irderId){
		throw new UnsupportedOperationException("Fail is not mocked!");
	}
}

Here is second dependency of testing class. It is also Spring component. This class will be spied (partially mocked) in test. Its method calculatePriceForOrder will be invoked unchanged. Second method will be stubbed.

@Service
public class PriceService {
	public int getActualPrice(Item item){
		throw new UnsupportedOperationException("Fail is not mocked!");
	}

	public int calculatePriceForOrder(Order order){
		int orderPrice = 0;
		for (Item item : order.getItems()){
			orderPrice += getActualPrice(item);
		}
		return orderPrice;
	}
}

And here is class under test. It  autowires dependencies above.

@Service
public class OrderService {

	@Autowired
	private PriceService priceService;

	@Autowired
	private OrderDao orderDao;

	public int getOrderPrice(int orderId){
		Order order = orderDao.getOrder(orderId);
		return priceService.calculatePriceForOrder(order);
	}
}

Finally here is test example. It uses field level annotations:

  • @InjectMocks – Instantiates testing object instance and tries to inject fields annotated with @Mock or @Spy into private fields of testing object
  • @Mock – Creates mock instance of the field it annotates
  • @Spy – Creates spy for instance of annotated field
public class OrderServiceTest {
	private static final int TEST_ORDER_ID = 15;
	private static final int TEST_SHOES_PRICE = 2;   
	private static final int TEST_SHIRT_PRICE = 1;

	@InjectMocks
	private OrderService testingObject;

	@Spy
	private PriceService priceService;

	@Mock
	private OrderDao orderDao;

	@BeforeMethod
	public void initMocks(){
		MockitoAnnotations.initMocks(this);
	}

	@Test
	public void testGetOrderService(){
		Order order = new Order(Arrays.asList(Item.SHOES, Item.SHIRT));
		Mockito.when(orderDao.getOrder(TEST_ORDER_ID)).thenReturn(order);

		//notice different Mockito syntax for spy
		Mockito.doReturn(TEST_SHIRT_PRICE).when(priceService).getActualPrice(Item.SHIRT);
		Mockito.doReturn(TEST_SHOES_PRICE).when(priceService).getActualPrice(Item.SHOES);

		//call testing method
		int actualOrderPrice = testingObject.getOrderPrice(TEST_ORDER_ID);

		Assert.assertEquals(TEST_SHIRT_PRICE + TEST_SHOES_PRICE, actualOrderPrice);
	}
}

So what happen when you run this test:

  1. First of all TestNG framework picks up @BeforeMethod annotation and invokes initMocks method
  2. This method invokes special Mockito call (MockitoAnnotations.initMocks(this)) to initialize annotated fields. Without this call, these objects would be null. Common mistake with this approach is to forget this invocation.
  3. When all the test fields are populated with desired values, test is called.

This example doesn’t include Spring context creation and Spring’s annotations are here only as examples for usage against production code. Test itself doesn’t include  any dependency to Spring and ignores all its annotations. In fact there could be used EJB annotations instead or it can be running against plain (non IoC managed) private fields.

Developers tend to think about MockitoAnnotations.initMocks(this) call as unnecessary overhead. But it is actually very handy, because it resets testing object and re-initializes mocks. You can use it for example

  • When you have various test methods using same annotated instances to ensure that various test runs doesn’t use same recorded behavior
  • When repetitive / parametrized tests are used. For example you can include this call into test  method itself and receive spy object as test parameter (as part of test case). This ability is very sexy in conjunction to TestNG @DataProvider feature (Will explain this in different blog post).

@Spy annotated object can be created in two ways

  • Automatically by Mockito framework if there is default (non-parametrized) constructor
  • Or explicitly initialized (e.g. when there is only non-default constructor)

Testing object annotated by @InjectMocks can be also initialized explicitly.

Example source code can be downloaded from GitHub.

Enterprise Integration with Spring Certification study notes and hints

Spring projects contain wide range of frameworks and abstraction APIs for Enterprise Integration. Best way to get an overview what Spring provides is to attend Enterprise Integration with Spring Training. It is unfortunately not affordable for everybody and I am not aware of any publication out there that explains Spring’s integration technologies altogether. Training includes:

  • Tasks and Scheduling support
  • Spring Remoting
  • Spring Web Services
  • Spring REST with Spring MVC
  • Spring JMS
  • Local and distributed transactions support
  • Spring Itegration
  • Spring Batch

I recently attended this course (thanks to my employer) and did certification exam afterwards. Now I would like to share my study notes and hints. These should provide you decent overview about Enterprise Integration with Spring. Study notes should cover everything needed for certification exam. But for passing the exam it isn’t enough just to memorize them. Unless you are familiar with these technologies already. They contain too many crucial information you can easily miss. You wouldn’t be successful until you get used each particular technology at least via examples or tutorials. I went through original SpringSource labs provided by training, few examples and tutorials. Also I was already familiar with Spring JMS, Spring MVC, Spring Integration and Spring transaction demarcation.

Study notes

  • Are based mainly on Spring reference documentations
  • Also contains some crucial principles and best practices Spring promotes that are usually not mentioned in reference documentations
  • Contains a lot of Spring XML configuration and Java code snippets
  • 57 pages
  • Download in PDF format
  • Download in ODT format (LibreOffice / OpenOffice)

Study hints, additional materials

  • Official Enterprise Integration with Spring certification study guide
  • Our training lecturer – Jorge Simao
    • provides very useful information on his site:
      • Certification reading list – [EDIT: Unfortunately reading list link was removed -> fire email to lubos.krnac@gmail.com]
    • gave us valuable advices for certification exam:
      • When there is question on what Spring supports, correct answers are often where Spring looks better.
      • Question are focused on Spring’s API and principles Spring promotes rather than underlying third party technologies.
  • Antoine Rey’s Java blog
    • Mock exam
    • Study notes
      • I was looking into these notes while I was creating mine
      • much shorter, but worth look into
      • unfortunately French only, but Google translator provides decent workaround

Examples

Suggested readings

You can schedule certification exam via Pearson VUE site, find SpringSource and your local certification center. Exam ID is SpringEIwSCertV1.0.

Hope these materials help you also gain this badge:

Enterprise Integration with Spring

Instantiate Spring bean with non-default constructor from another bean

I’d like to show how to instantiate Spring bean with non-default constructor (constructor with parameters) from other Spring driven bean because it seems to me that a lot of Java developers don’t know that this is possible.

First of all, simple annotation based Spring configuration. It’s scanning target package for Spring beans.

@Configuration
@ComponentScan("sk.lkrnac.blog.componentwithparams")
public class SpringContext {
}

Here is component with non-default constructor. This component needs to be specified as prototype, because we will be creating new instances of it. It also needs to be named (will clarify why below).

@Component(SpringConstants.COMPONENT_WITH_PARAMS)
@Scope("prototype")
public class ComponentWithParams {
 private String param1;
 private int param2;

 public ComponentWithParams(String param1, int param2) {
  this.param1 = param1;
  this.param2 = param2;
 }

 @Override
 public String toString() {
  return "ComponentWithParams [param1=" + param1 + ", param2=" + param2
    + "]";
 }
}

Next component instantiates ComponentWithParams. It needs to be aware of Spring’s context instance to be able to pass arguments non-default constructor.
getBean(String name, Object... args) method is used for that purpose. First parameter of this method is name of the instantiating component (that is why component needed to be named). Constructor parameters follow.

@Component
public class CreatorComponent implements ApplicationContextAware{
 ApplicationContext context;

 public void createComponentWithParam(String param1, int param2){
  ComponentWithParams component = (ComponentWithParams)
    context.getBean(SpringConstants.COMPONENT_WITH_PARAMS, 
      param1, param2);
  System.out.println(component.toString() + " instanciated...");
 }

 @Override
 public void setApplicationContext(ApplicationContext context)
   throws BeansException {
  this.context = context;
 }
}

Last code snippet is main class which loads Spring context and runs test.

public class Main {

 public static void main(String[] args) {
  AnnotationConfigApplicationContext context = 
    new AnnotationConfigApplicationContext(SpringContext.class);
  CreatorComponent invoker = context.getBean(CreatorComponent.class);

  invoker.createComponentWithParam("First", 1);
  invoker.createComponentWithParam("Second", 2);
  invoker.createComponentWithParam("Third", 3);
  context.close();
 }
}

Console output:

ComponentWithParams [param1=First, param2=1] instantiated...
ComponentWithParams [param1=Second, param2=2] instantiated...
ComponentWithParams [param1=Third, param2=3] instantiated...

And that’s it. You can download source code from Github.