Mock constructor

Foreword

If you already read some other blog post about unusual mocking, you can skip prelude via this link.

I was asked to put together examples how to mock Java constructs well know for their testability issues:

I am calling these techniques unusual mocking. I was worried that such examples without any guidance can be widely used by teammates not deeply experienced in mocking frameworks.

Developers practicing TDD or BDD should be aware of testability problems behind these constructs and try to avoid them when designing their tests and modules. That is the reason why you probably wouldn’t be facing such unusual mocking often on project using these great programming methodologies.

But sometimes you have to extend or maintain legacy codebase that usually contains low cohesive classes. In most cases there isn’t time in current hectic agile world to make such class easy to unit test standard way. When you are trying to unit test such class you often realize that unusual mocking is needed.

That is why I decided to create and share refactoring considerations alongside with examples and workarounds for unusual mocking. Examples are using Mockito and PowerMock mocking frameworks and TestNG unit testing framework.

Mock constructor

Refactoring considerations

  • If your testing method creates instance/s of some type, there are two possibilities what can happen with these instances
    • Created instance/s are returned from testing method. They are in this case part of the testing method API. This can be tested by verifying against created instances rather than constructor method call. If target instances doesn’t have hashCode/equals contract implemented, you can still create test specific comparator to verify created data.
    • Created instances are used as parameter/s passed to some dependency object. This dependency object of testing class is most probably mocked. In this case it’s better idea to capture arguments of dependency method call and verify them. Mockito offers good support for this.
    • Created instances are temporary objects that support testing method job. In this case you shouldn’t care about creation of these instances, because you should treat testing module as black box that doing the job, but you don’t know how.
  • Create factory class for constructing instances and mock it standard way.
  • If that fits to requirement -> Abstract factory design pattern

Workaround using Mockito

This is my preferred technique when I need to mock constructor. I believe that minor exposing of internal implementation in flavor to enhance testability of testing module is much lower risk for project than fall into bytecode manipulation mocking  framework like PowerMock or JMockIt.

This technique involves:

  • Encapsulating the constructor into method with default access modifier
  • Partial mock (spy) is used to mock this method during testing

Mockito example covers:

  1. Partial mocking of factory method
  2. Verifying of mocked factory method call

Class under test:

public class CarFactoryMockito {
	Car carFactoryMethod(String type, String color) {
		return new Car(type, color);
	}

	public Car constructCar(String type, String color) {
		carFactoryMethod(type, color);
		// ... other logic needed to be tested ...
		return carFactoryMethod(type, color);
	}
}

Test:

public class CarFactoryMockitoTest {
	private static final String TESTING_TYPE = "Tatra";
	private static final String TESTING_COLOR = "Black";

	@Test
	public void testConstructCar() {
		CarFactoryMockito carFactory = new CarFactoryMockito();
		CarFactoryMockito carFactorySpy = Mockito.spy(carFactory);

		Car mockedInstance = Mockito.mock(Car.class);
		Mockito.doReturn(mockedInstance).when(carFactorySpy)
				.carFactoryMethod(TESTING_TYPE, TESTING_COLOR);

		// invoke testing method
		Car actualInstance = carFactorySpy.constructCar(TESTING_TYPE,
				TESTING_COLOR);

		Assert.assertEquals(actualInstance, mockedInstance);
		// ... verify other logic in constructCar() method ...
		Mockito.verify(carFactorySpy, Mockito.times(2)).carFactoryMethod(
				TESTING_TYPE, TESTING_COLOR);
	}
}

Usage of PowerMock

Before usage of this example, please carefully consider if it is worth to bring bytecode  manipulation risks into your project. They are gathered in this blog post. In my opinion it should be used only in very rare and non-avoidable cases.

Test shows how to mock constructor directly by PowerMock. Example covers:

  1. Mocking of constructor
  2. Verifying of constructor call

Class under test:

public class CarFactoryPowerMock {
	public Car constructCar(String type, String color) {
		new Car(type, color);
		return new Car(type, color);
	}
}

Test:

/**
 * Demonstrates constructor mocking by PowerMock.
 * <p>
 * NOTE: Prepared in PowerMock annotation {@link PrepareForTest} should be class
 * where is constructor called
 */
@PrepareForTest(CarFactoryPowerMock.class)
public class CarFactoryPowerMockTest extends PowerMockTestCase {
	private static final String TESTING_TYPE = "Tatra";
	private static final String TESTING_COLOR = "Black";

	@Test
	public void testConstructCar() throws Exception {
		Car expectedCar = Mockito.mock(Car.class);
		PowerMockito.whenNew(Car.class)
				.withArguments(TESTING_TYPE, TESTING_COLOR)
				.thenReturn(expectedCar);

		// invoke testing method
		CarFactoryPowerMock carFactory = new CarFactoryPowerMock();
		Car actualCar = carFactory.constructCar(TESTING_TYPE, TESTING_COLOR);

		Assert.assertEquals(actualCar, expectedCar);
		// ... verify other logic in constructCar() method ...
		PowerMockito.verifyNew(Car.class, Mockito.times(2)).withArguments(
				TESTING_TYPE, TESTING_COLOR);
	}
}

Links

Source code can be downloaded from Github.

Other unusual mocking examples:

Mock private method

Foreword

If you already read some other blog post about unusual mocking, you can skip prelude via this link.

I was asked to put together examples how to mock Java constructs well know for their testability issues:

I am calling these techniques unusual mocking. I was worried that such examples without any guidance can be widely used by teammates not deeply experienced in mocking frameworks.

Developers practicing TDD or BDD should be aware of testability problems behind these constructs and try to avoid them when designing their tests and modules. That is the reason why you probably wouldn’t be facing such unusual mocking often on project using these great programming methodologies.

But sometimes you have to extend or maintain legacy codebase that usually contains low cohesive classes. In most cases there isn’t time in current hectic agile world to make such class easy to unit test standard way. When you are trying to unit test such class you often realize that unusual mocking is needed.

That is why I decided to create and share refactoring considerations alongside with examples and workarounds for unusual mocking. Examples are using Mockito and PowerMock mocking frameworks and TestNG unit testing framework.

Mock private method

Refactoring considerations

Private method that is needed to be mocked can be in:

  • testing class (will call it TC)
  • direct dependency of testing class (will call is DDC)
  • class that is not direct dependency of testing module (will call it NDDC)

Re-factoring techniques to consider:

  • If the private method is in TC, it is a good sign that TC has low cohesion (has too many responsibilities) and logic behind private method should be extracted into separate class. After this refactoring, private method in TC becomes public in new dependency class. Than it is possible to mock it standard way.
  • If the private method is in DDC, concerns of TC and DDC modules are not separated properly. It means you are trying to test some logic from DDC in test for TC. Consider moving this logic to TC or to separate module. Private method than becomes public and can be mocked standard way.
  • If the private method is in NDDC, you are probably creating integration test instead of unit test. Unit test in theory should be testing module in isolation. That means to mock all direct dependencies (sometimes it’s easier to test with real objects when they are simple and independent enough). Consider:
    • Creation of unit test first. You can decide later if integration test is needed for group of modules you trying to test.
    • Find easier to mock boundaries for your integration test (you can find a clue in unit test for NDDC if exists)
    • Refactor NDDC according refactoring practises mentioned for TC and DDC above, update it’s unit test (also all tests affected by refactoring), and use created public method as boundary for your integration test.

Workaround using Mockito

This is my preferred technique when I need to mock private method. I believe that minor exposing of internal implementation in flavor to enhance testability of testing module is much lower risk for project than fall into bytecode manipulation mocking  framework like PowerMock or JMockIt.

This technique involves:

  • Changing private access modifier to default
  • Partially mock testing object by using spy

Mockito example covers:

  1. Mocking of changed default method with return value
  2. Mocking of changed changed default void method
  3. Verifying of changed default method calls

Class under test:

public class Train {
	public int compose() {
		for (int idx = 0; idx < getWagonsCount(); idx++) {
			addWagon(0);
		}
		return getWagonsCount();
	}

	/**
	 * Access modifier was changed from private to default to enhance
	 * testability
	 */
	// private
	int getWagonsCount() {
		throw new UnsupportedOperationException("Fail if not mocked!");
	}

	/**
	 * Access modifier was changed from private to default to enhance
	 * testability
	 */
	// private
	void addWagon(int position) {
		throw new UnsupportedOperationException(
				"Fail if not mocked! [position=" + position + "]");
	}
}

Test:

@Test
public void testCompose() {
	Train train = new Train();
	Train trainSpy = Mockito.spy(train);

	//notice different Mockito syntax for spy   
	Mockito.doReturn(TESTING_WAGON_COUNT).when(trainSpy).getWagonsCount();
	Mockito.doNothing().when(trainSpy).addWagon(0);

	// invoke testing method
	int actualWagonCount = trainSpy.compose();

	Assert.assertEquals(actualWagonCount, TESTING_WAGON_COUNT);
	Mockito.verify(trainSpy, Mockito.times(TESTING_WAGON_COUNT))
			.addWagon(0);
}

Usage of PowerMock

Before usage of this example, please carefully consider if it is worth to bring bytecode  manipulation risks into your project. They are gathered in this blog post. In my opinion it should be used only in very rare and non-avoidable cases.

Test shows how to mock private method directly by PowerMock. Example covers:

  1. Mocking of private method with return value
  2. Mocking of private void method
  3. Verifying of private method calls

Class under test:

public class Truck {
	public double addLoad(Collection<Double> boxWeightsToAdd) {
		for (Double boxWeight : boxWeightsToAdd) {
			addBoxToLoad(boxWeight);
		}
		return getLoadWeight();
	}

	private double getLoadWeight() {
		throw new UnsupportedOperationException("Fail is not mocked!");
	}

	private void addBoxToLoad(double weight) {
		throw new UnsupportedOperationException("Fail is not mocked! [weight="
				+ weight + "]");
	}
}

Test:

@PrepareForTest(Truck.class)
public class TruckTest extends PowerMockTestCase {
	private static final double TESTING_LOAD_WEIGHT = 200;
	private static final double TESTING_BOX_WEIGHT = 100;

	@Test
	public void testTestingMethod() throws Exception {
		Truck truck = new Truck();
		Truck truckSpy = PowerMockito.spy(truck);

		PowerMockito.doReturn(TESTING_LOAD_WEIGHT).when(truckSpy,
				"getLoadWeight");
		PowerMockito.doNothing().when(truckSpy, "addBoxToLoad",
				TESTING_BOX_WEIGHT);

		// call testing method
		Collection<Double> boxesWeights = Arrays.asList(TESTING_BOX_WEIGHT,
				TESTING_BOX_WEIGHT);
		double actualLoad = truckSpy.addLoad(boxesWeights);

		Assert.assertEquals(actualLoad, TESTING_LOAD_WEIGHT);
		PowerMockito.verifyPrivate(truckSpy, Mockito.times(2)).invoke(
				"addBoxToLoad", TESTING_BOX_WEIGHT);
	}
}

Links

Source code can be downloaded from Github.

Other unusual mocking examples:

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.

Share Dependencies Between Tycho and Plain Maven project

It is well known that RCP bundle is not the Maven’s best friend. Peacemaker between them is Maven’s plug-in Tycho. I was recently migrating my free time RCP based project into Maven Tycho. My goal was to share dependencies between normal Maven project and Tycho driven project. Plain maven project is needed for running TestNG tests (TestNG is not supported by Tycho).

There are two approaches how to automatically handle dependencies of Eclipse 4 RCP based project driven by Tycho:

  • manifest-first – this approach follows standard RCP/OSGi dependency mechanisms. All dependencies has to be also assembled into bundles. This is preferred and nicely described in tutorial suggested by Tycho’s website. It is hosted on github. But there are few problems complicating my goal:
    • It is needed to find existing bundle or create one for every dependency. Unhandy.
    • If I would use manifest-first approach, bundle dependencies wouldn’t be visible by non Tycho maven projects. I would need to have two set of dependencies. Redundancy.
  • pom-first – this is alternative approach when dependencies are packed into bundle by maven-bundle-plugin and this is used as dependency to project’s bundle. This approach is described here. Problem of this approach:
    • It is working only for Maven build and dependencies are not picked up by Eclipse.

Finally got the clue here (in the last approach) and came up with solution that is maybe not that pretty, but the dependencies are specified at one place and even Maven as well as Eclipse can pick them up. It is using some aspects both mentioned approaches.

I will show here only configuration crucial for my workaround. Whole project can be found on google code page. Let me describe maven projects structure:

artefact-inheritance

discography-organizer.parent

Contains various properties used by child poms. Is also used to run build of all sub-modules.

discography-organizer.dependencies.parent

Shared dependencies are specified here

discography-organizer.dependencies.bundle

Is doing two important steps:

1. maven-bundle-plugin to pack dependencies

<plugin>
  <groupId>org.apache.felix</groupId>
  <artifactId>maven-bundle-plugin</artifactId>
  <version>2.1.0</version>
  <extensions>true</extensions>
  <configuration>
    <instructions>
      <Export-Package>*; -split-package:=merge-last</Export-Package>
    </instructions>
  </configuration>
</plugin>

2. maven-antrun-plugin to copy packed jar with all dependencies into location where it can be picked up by RCP project

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-antrun-plugin</artifactId>
  <version>1.7</version>
  <executions>
    <execution>
      <phase>package</phase>
      <configuration>
        <target>
          <copy tofile="${temp.dependencies.folder}/dependencies.jar">
            <fileset dir="${project.build.directory}" includes="*.jar" />
          </copy>
        </target>
      </configuration>
      <goals>
        <goal>run</goal>
      </goals>
    </execution>
  </executions>
</plugin>

discography-organizer.bundle

Main RCP bundle project driven by Tycho. Expect Tycho call, there are two important configurations done:

1. In plugin.xml configuration on tab “Runtime” choose dependency jar created by discography-organizer.dependencies.bundledependency-plugin-xml

2. Pack main project classes into jar. This will be used by testing project discography-organizer.tests

Packing of application classes into jar:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-antrun-plugin</artifactId>
  <version>1.7</version>
  <executions>
    <execution>
      <phase>package</phase>
      <configuration>
        <target>
          <jar destfile="${temp.dependencies.folder}/${bundle.name}-TESTING.jar" 
             basedir="${project.basedir}/bin"/>
        </target>
      </configuration>
      <goals>
        <goal>run</goal>
      </goals>
    </execution>
  </executions>
</plugin>

Pom file for this test dependency:
files-in-bundle

<groupId>sk.lkrnac.discorg</groupId>
<artifactId>discography-organizer.bundle</artifactId>
<version>TESTING</version>
<packaging>jar</packaging>

discography-organizer.tests

Normal maven project with tests. It is reading testing classes from jar created by discography-organizer.bundle

<dependency>
  <groupId>sk.lkrnac.discorg</groupId>
  <artifactId>${bundle.name}</artifactId>
  <version>TESTING</version>
  <scope>system</scope>
  <systemPath>${temp.dependencies.folder}/${bundle.name}-TESTING.jar</systemPath>
</dependency>

And that’s it. Dependencies needed by main bundle or test artifacts are packed into jar files. This workaround has side effects that I really don’t like. Dependencies are ugly packed in one jar for main bundle. But I can live with that because this approach enables me to combine features of Tycho and non-Tycho maven plug-ins. I am planning to use another Tycho’s features (automatic building and JUnit plug-in tests) and I have good start point for it.

If you can think of some simpler or more elegant solution please don’t hesitate to comment it. Thanks