Using "Mocking" to make your code testing easier

On their end, the developers have also understood that testing their code allows them to detect errors in their programming much more quickly and to insure themselves that their work is of good quality. The tests also allow the developers to guarantee that the behavior of their code will remain consistent even if another member of the development team had to correct or modify it.

In today’s information technology projects, all project managers know the critical importance of performing important code coverage on their team's code. Indeed, this investment is costly in terms of development time, but the return on investment is proven since we know that the real main cost of the application is the one for its maintenance, and not the one for its development.

On their end, the developers have also understood that testing their code allows them to detect errors in their programming much more quickly and to insure themselves that their work is of good quality. The tests also allow the developers to guarantee that the behavior of their code will remain consistent even if another member of the development team had to correct or modify it.

The testing also forces the engineer to simplify his or her code in order to make it easier to test, keeping true to the leitmotiv “Keep it simple.” The methods are short, have limited responsibilities, and are less complex. By keeping things simple, it is also easier for the developer to Mock the behaviors for which the part with tested code is not responsible.

This article will, therefore, talk about “Mocking” but from an unusual perspective.

As a reminder, “in object-oriented programming, mock objects are simulated objects that mimic the behavior of real objects in controlled ways. A programmer typically creates a mock object to test the behavior of some other object,” real but linked to an inaccessible or non-implemented object. The latter one is then replaced by a mock object. [ref. Wikipedia.com, Wikipedia.fr].

In Java, there are many libraries such as EasyMock or Mockito that really help developers with this task. However, the developer is always limited to the information in these libraries. Indeed, sometimes the developer looks to simulate a private/final method’s behavior, or the behavior of a static method.

It is in fact absolutely possible to do this with base tools, but at a high price in terms of design and other artifacts. There are still so many points that require additional investments for the developers to reach their goal.

Thankfully, other developers very often have stumbled upon similar problems and have already contemplated them in order to find solutions. This is the case for the extension of the PowerMock library (for which you will find sources and documentation here). PowerMock does not work on its own: It is just an extension that can be used in conjunction with EasyMock or Mockito.

Thanks to this library, it is possible to mock almost everything. The library works at the lowest level since it directly manipulates the Java classes’ bytecodes.

Here is a concrete example to illustrate Powermock’s simplicity of use and power. The objective here is to modify the behavior of a static method called from another method. The base library is Mockito.

The class that contains the static method whose behavior will need to be modified:

public class StaticMethods {

public static final String test(){

return "normal string";

}

}

Below is the class containing the method to test with a static call is presented:

public class CallingClass {

public String callStaticMethods(){

return StaticMethods.test();

}

}

Therefore, the objective is to modify the behavior of the method “test()” from the class “CallingClass”.

To start with, you just need to create a standard unit test.

public class TestStaticMethods {

private CallingClass callingClass = new CallingClass();
@Test
public void testMethodThatCallsStaticMethod(){

String res = callingClass.callStaticMethod();
Assert.assertEquals("modified string",res);

}

}

After executing this first unit test it is clear that it will fail.

This is how to modify the unit test using PowerMock to achieve the target objective.
First, you have to add the following annotations at the beginning of the test class:

// Specify the use of PowerMock
@RunWith(PowerMockRunner.class)
// Specify which PowerMock class will have to modify
@PrepareForTest(StaticMethods.class)
public class TestStaticMethods {

...

}

Next, you have to outline the parameters for the behavior you want:

// Specify the use of PowerMock
@RunWith(PowerMockRunner.class)
// Specify which class PowerMock will have to modify
@PrepareForTest(StaticMethods.class)
public class TestStaticMethods {

private CallingClass callingClass = new CallingClass();
@Test
public void testMethodThatCallsStaticMethod() {

// Specify the intention to modify the behavior of the static methods in the class.
PowerMockito.mockStatic(StaticMethods.class);
// Standard use of Mockito to modify the wanted behavior
Mockito.when(StaticMethods.method()).thenReturn("modified string");
// Call the method to test
String res = callingClass.callStaticClass();
Assert.assertEquals("modified string", res);

}

}

With these small modifications, the test is now a success and the target objective has been met. The example presented in this article is a simple way to use PowerMock. However, this library extension offers many other functionalities and, as shown here, its application is not very costly. With this extra utility, developers are even better armed to cover their code even more extensively and to test almost all situations.

View the French version of this article here.

Digital news!

Are you as digitally addicted as we are? We can supply you with a regular dose of digital news. Simply sign-up, or click to Follow us online.

About the author

Grégory Brissonnette
Grégory Brissonnette