sábado, diciembre 11, 2010

Hit The Road Jack and Don't You Come Back No More

Today, thanks of Neal Ford (I have met him in Devoxx 2010[lovely presentation]), I have been reviewing its presentations and I have found interesting one called "Unit Testing That's Not So Bad: Small Things That Make a Big Difference". In this presentation are showed tools for testing like JUnit, InfiniTest, Jester, ... also shows some strategies for writting your tests, and finally a real revelation, you can also test your PRIVATE methods. More often than not, you create an interface that have a public method, and then a class that implements this interface (functionality), and because of code clean you create some private methods that help public method to acquire its porpoise. And then comes test part, you write testing code for your public method, you run tests, 100% coverage, and that's all, you think you have got a perfect code, but, ... that's not true, you could have a bug to a private method that is not reflected in final result (for example a divide by zero), and because you have not write tests for your private methods, you have not though about possible results and although your code have 100% coverage, it is not perfect.

Furthermore, your public method can be an aggregation of several private methods, and would not be funny and easier to test private methods alone? I am sure you are thinking yourself, "Yes would be perfect for that class I wrote some time ago where my private methods contains 60 lines of code each one".

Imagine next example:

We need to develop a software that calculates how many egg-cups shall be required for placing "n" eggs. We have a method that returns the number of eggs (imagine that this value is returned from a complex method like connecting to webservice, connecting to database, ...), also another complex method returns the number of positions in each egg-cup.

So Class shall look something like:

public class EggCupCalculation {
private int numberOfEggs = 0;
private int numberOfHoles = 0;
public int calculateNumberOfEggCups() {
int numberOfEggs = getNumberOfEggs();
int numberOfHoles = getNumberOfEggCupHoles();
return calculateNumberOfRequiredEggCups(numberOfEggs, numberOfHoles);
}

private int calculateNumberOfRequiredEggCups(int numberOfEggs, int numberOfHoles) {
int requiredEggCups = numberOfEggs/numberOfHoles;
if(areEggsRemaining(numberOfEggs, numberOfHoles)) {
requiredEggCups++;
}
return requiredEggCups;
}
private boolean areEggsRemaining(int numberOfEggs, int numberOfHoles) {
return numberOfEggs%numberOfHoles>0;
}
private int getNumberOfEggCupHoles() {
// Complex operation like accessing database for retrieving number of egg cup holes.
return this.numberOfHoles;
}

private int getNumberOfEggs() {
// Complex operation like accessing external resource
return this.numberOfEggs;
}


public void setNumberOfHoles(int numberOfHoles) {
this.numberOfHoles = numberOfHoles;
}

public void setNumberOfEggs(int numberOfEggs) {
this.numberOfEggs = numberOfEggs;
}
}

Where both class attributes has been used for simplyfing the example, and not requiring a mock.

And Test Class:

public class WhenNumberEggCupsIsCalculated {

@Test
public void twenty_Five_Eggs_Should_Require_Three_Egg_Cups(){
//Simple test with simple logic for understanding propose
EggCupCalculation eggCupCalculation = new EggCupCalculation();

//For avoiding a complicated test, this is for teaching propose, a mock will not be used.
eggCupCalculation.setNumberOfEggs(25);
eggCupCalculation.setNumberOfHoles(12);
assertThat(eggCupCalculation.calculateNumberOfEggCups(), is(3));
}

@Test
public void twenty_Four_Eggs_Should_Require_Two_Egg_Cups() {
//Simple test with simple logic for understanding propose
EggCupCalculation eggCupCalculation = new EggCupCalculation();

//For avoiding a complicated test, this is for teaching propose, a mock will not be used.
eggCupCalculation.setNumberOfEggs(24);
eggCupCalculation.setNumberOfHoles(12);
assertThat(eggCupCalculation.calculateNumberOfEggCups(), is(2));
}
}

And as you can see 100% coverage is acquired. And now you can think, well my code is perfect, cause I have thought about two possible cases, when the division have no rest or when have rest and one more egg cup is required.

Yeeeeeees, but what's happen if one day getNumberOfEggCupHoles() returns a 0, meaning that eggs cannot be into an egg cup? Then Booooom.

I am sure that if you had tested private method calculateNumberOfRequiredEggCups() you had seen that a divide by zero could occur.

This is a simple example, imagine with real business case.

So here are three possible solutions for testing private methods, every one is free to choose the best for him.

Solution 1:

Make all methods public (or package) scope, put your tests in same package (but in different source folder) as classes, and write your tests. It is an ugly possibility you modify your development, breaking OOP principles for test.

Solution 2:

Use reflection, that big omitted thing. How about using reflection for accessing to private methods? Good, let's look code:



@Test
public void twenty_Five_Eggs_Should_Require_Three_Egg_Cups(){
//Simple test with simple logic for understanding propose
EggCupCalculation eggCupCalculation = new EggCupCalculation();

assertThat(getNumberEggCups(eggCupCalculation, 25, 12), is(3));
}

@Test
public void twenty_Four_Eggs_Should_Require_Two_Egg_Cups() {
//Simple test with simple logic for understanding propose
EggCupCalculation eggCupCalculation = new EggCupCalculation();
assertThat(getNumberEggCups(eggCupCalculation, 24, 12), is(2));
}
@Test
public void twenty_Four_Eggs_Without_Egg_Cups_Should_Require_No_Egg_Cups() {
//Simple test with simple logic for understanding propose
EggCupCalculation eggCupCalculation = new EggCupCalculation();
assertThat(getNumberEggCups(eggCupCalculation, 24, 0), is(0));
}
private int getNumberEggCups(EggCupCalculation eggCupCalculation, int numberEggs, int numberEggCupHoles) {
try {
Method m = EggCupCalculation.class.getDeclaredMethod("calculateNumberOfRequiredEggCups", int.class, int.class);
m.setAccessible(true);
return (Integer)m.invoke(eggCupCalculation, numberEggs, numberEggCupHoles);
} catch (SecurityException e) {
fail();
} catch (NoSuchMethodException e) {
fail();
} catch (IllegalArgumentException e) {
fail();
} catch (IllegalAccessException e) {
fail();
} catch (InvocationTargetException e) {
fail(e.getMessage());
}
return -1;
}


Well now you can access private method, you still have the problem, because of divided by 0, but your code does not pass all tests. That's good, you can play with parameters of private methods and find possible errors and/or reproduce strange scenarios. Ok, it is a good idea, but maybe too complicated, you must use reflection and also a lot of possible exceptions (test fail), not because your business but because of reflection. So it is not a clean solution or at least simple to read. Of course it is a valid solution.

Solution 3:

Using Groovy. Expand your mind, there is some script languages (supported nativly by JDK), that can make your life easier, and this is one case. How about that groovy file:

class WhenNumberEggCubsIsCalculatedGroovy {

@Test public void twenty_Four_Eggs_Should_Require_Two_Egg_Cups() {
def m = EggCupCalculation.class.getDeclaredMethod("calculateNumberOfRequiredEggCups",int.class, int.class)
m.accessible = true
assertThat m.invoke(new EggCupCalculation(), 12,6), is(2)
}
@Test public void twenty_Four_Eggs_Should_With_No_Egg_Cups_Should_Return_Zero() {
def m = EggCupCalculation.class.getDeclaredMethod("calculateNumberOfRequiredEggCups",int.class, int.class)
m.accessible = true
assertThat m.invoke(new EggCupCalculation(), 12,0), is(0)
}
}

Easy to understand, and easy to test, not catch sequence, not casts, not complicated expressions. If you had tested private methods (knowing that a division is performed), then you would see that a division by 0 can occurs and you modified the code for not crashing.

Now you have three valid options for testing private methods, choose the best for you. Of course this a simple example and everybody knows that this particular example is difficult that occurs in real examples, but this is only a pedagogic example.

And now it is time to think about what private methods are candidate to be tested. Not all, but these private methods that contains important/critical business code should be tested.

In future posts, I will show you how to integrate maven into groovy test, so java native junit tests and groovy junt tests are runned.

sábado, noviembre 27, 2010

La Mer Au Ciel d'Ete Confond


Have you ever started a war with java.util.Calendar class? I hope no, but unfortunately a lot of developed applications deals with Date and Time. Calendar class is a singleton class for manage time, but one never knows exactly how to work with it. You know you have methods for add and subtract time, but nothing more. Now I ask, How about periods of time, durations, intervals...? you need to develop a class for managing all these requirements. Let's take an example:

Imagine we want to compare if current date is Christmas Date.

Calendar compares all its fields, so year, month, day, minutes, seconds, ... are compared, but wait, Christmas day does not depend on year, every year has its Christmas Day. So a "Util" class is developed for treating with this situation. This class would look something like:

Calendar christmasDay = Calendar.getInstance();
christmasDay.set(MONTH, 12);
christmasDay.set(DATE, 25);

Calendar now = Calendar.getInstance();
if(christmasDay.get(MONTH)==now.get(MONTH) && christmasDay.get(MONTH)==now.get(DATE)) {
return true;
} else {
return false;
}

Next example:

Boulangerie example. Our brother-in-law have a bakery, and wants to automatize oven, so a each bread stays only 15 minutes inside oven (of course not all breads gets into oven at same time). With Calendar/Date class this logic would look something like:

static long FIFTEEN_MINUTES = 15 * 60 * 1000;

long startOvenTimeBread1 = System.currentTimeInMillis();
//Thread Polling
....
long currentTime = System.currentTimeInMillis();

if(currentTime>=startOvenTimeBread1 + FIFTEEN_MINUTES) {
//bread ok
}

As you can see first example it is tedious because you must get all required attributes, and compare them with current time. In second example is not as hard as first but you lost the sensation of working with time, all are longs, and the only way to understand what is each long is with variable name.

So Yes working with Dates/Times in JDK looks like a suicide, but here comes JSR-310 (JDK-8?included).

Let's rewrite the same examples but with JSR-310 API.

Christmas Day example:

MonthDay christmasDay = MonthDay.of(12, 25);
MonthDay now = MonthDay.nowSystemClock();

boolean isChristmas = now.equals(christmasDay);

I think more readable than using Calendars, no problem with hours, minutes, seconds, years, ... MonthDay class manages all. These kind of classes in JSR-310 are known as Partials because they only represents partial time.

Now Boulangerie needs our help. As you have observed, the first problem in that case is that you only manages longs, and as a developer you don't have the feeling of working with time. Also an ugly comparison is required.

How make code looking better:

Duration duration = Duration.ofStandardMinutes(15);

Instant insertedBreadInstant = Instant.nowSystemClock();
Instant bakedBreadInstant = insertedBreadInstant.plus(duration);

//Thread Polling
...
boolean isBaked = bakedBreadInstant.isBefore(Instant.nowSystemClock());


Well more instructions than long approach are used, but don't you think that this implementation is easily read, and you know what is each field.

So don't you think JSR-310 specification and RI implementation is a really useful API? more powerful than current Calendar/Date classes.

Now it is only time to wait for being built-in JDK, but of course you can download RI implementation from java.net.

martes, noviembre 23, 2010

... Una Vez Está Bien Pero Dos Está Mal ...

Hamcrest is about making your test readable. Hamcrest is a framework that allows us to use object matchers for developing stylized sentences in assertions.

Let's look some examples:

Why write this:

double calculatedValue = 1000D;
...
assertEquals(1000, calculatedValue, 0)


When you can write this:

assertThat(calculatedValue, is(1000));

Or Why write off all this code:

List validResults = Arrays.asList("4+", "3+", "2+");
String result = .....;

assertFalse(validResults.contains(result));


When you can write:

assertThat("1+", not(isIn(validResults)));

Three points should get your attention:

I. Using assertEquals (in our case with double) is not readable, what is the meaning of third parameter in previous example ?¿ What's happen if instead of 0 I pass a 1?¿.

II. When you speak yourself repeating a requirement, you say: "calculated value should be 1000", but it is rarely common to think "1000 should be my calculated value". Moreover, for example String assertEquals method contains 2 parameters, which of two are the expected value and current value?

III. Flexible notation in contrast to JUnit notation. For specifying that an element cannot be into a collection, in Junit assertFalse is used, and that's sounds strange using with a contains method of a list you can misunderstood exactly what are being test. Look Hamcrest expression, no possible error, we are asserting that "1+" not in validResults. Hamcrest has a module for treating collections expressions, like anyOf, isOneOf, hasItem, hasItems...

But wait, there is more, you can also build you own Hamcrest Matcher. A matcher is the responsible for validating if something is what expected. Hamcrest comes with a lot of built-in Matchers, but what's happen if we need one new matcher? Let's look an example:

Hamcrest does NOT comes with File matchers. We need to validate if after our business logic, a file is created in a directory.

- In Junit like expressions, would look something like:

final File createdFile = new File("test1");
assertTrue(createdFile.exists());


- In Hamcresst with built-in matchers:

final File createdFile = new File("test1");
assertThat(createdFile.exists(), is(true));


Maybe better than JUnit but expressiveness may be missing.

- What about that:

final File createdFile = new File("test1");
assertThat(createdFile, exists());


Better I think.

But a Matcher for asserting that, does not exists, so let's write one:

public class ExistsFileMatcher extends TypeSafeMatcher {

@Override
public void describeTo(final Description description) {
description.appendText("does not exists.");
}

@Override
public boolean matchesSafely(final File expectedFile) {
return expectedFile.exists();
}

@Factory
public static Matcher exists() {
return new ExistsFileMatcher();
}

}

One will agree that is so simple, only one method that validates the expression, other one that describes the error, and finally a factory.

And this matcher can be used in conjunction with other matchers. It is also valid that one:

final File createdFile = new File("test1");
assertThat(createdFile, not(exists()));


And that's Hamcrest, don't you think is a better way to express assertions rather than plain JUnit?

domingo, noviembre 14, 2010

What Colour is God? Why Can't You Tell Me.

Usually one tend to think about testing as a residual part of development. Nothing further from reality. Testing, so JUnit classes, needs to be treated as "business code". Must follow naming conventions, code must be sectioned, and of course must be readable. For this reason, John Ferguson Smart has its own rules that I would like to summarize and comment:

As John Ferguson Smart told in his entries, there are 5 rules that all JUnit classes must follows, that rules are:

I. Don't say "test", say "should".


JUnit test should pass, but "should pass", maybe there is something wrong in classes that makes test fail, for this reason we are writing off tests. Also, test cases must be validated with requirements, because a requirement is specified as should/shall not with test, same nomenclature is used. Thanks of this improvement, it is easy validating requirements using tests.

Also as Neal Ford suggests each word of your test method name must be separated with '_' character. I find this suggestion so useful because you don't need to use your mind for parsing camel case methods. Of course this only applies to JUnit methods (Yes the only exception between delivery classes and test classes). With this small change your test department will be thankful how fast can validate requirements.

For example the method: testTransfer must be changed to transferShouldDeductSumFromSourceAccountBalance as John Smart suggests, but another change is better, and is changing to: transfer_Should_Deduct_Sum_From_Source_Account_Balance and that's more readable.

II. Don't test classes, test their behavior.


Of course because test cases are related to use cases, tests must validate behavior. This also affects on avoiding testing your classes for the only porpouse of reaching 100% of coverage. 100% of coverage is important, but guarantees nothing, if you don't keep in mind that you must test behavior.

III. Test class names are important too.


Of course when you want to locate where some behavior is tested, it helps the name of your test. Class names must answer the question: When is this behavior applicable? as method names should answer the question: What behavior are we testing?.

What you think is better test class name: TransactionTest or WhenMoneyTransactionIsCommited. Both test names are valid but second one is descriptive about what behavior are you testing.

IV. Structure your tests well.


Test classes are also business classes and for that reason they also have the right to be refactored, kept clean and readable. For that reason is so important to write tests consistently. A really good suggestion is divide each test in three main sections, Given-When-Then. Only with tabs and CR can work perfectly, but you can also use frameworks like JBehave or Easyb.

V. Test are deliverables too.


Tests must be treated as commercial code, not because your client does not see test classes, you can ignore them from static analysis.

jueves, marzo 11, 2010

... Volver, con la frente marchita, las nieves del tiempo platearon mi sien...



Today I am going to talk about building and adding a simple addon to Spring-Roo. I will not talk about what is Roo or about their benefits.

Roo is built on an add-on architecture that enables different types of Java applications to be built. For this reason is so important to know how to build new addons for Spring-Roo.

Our addon:

First of all install Spring-Roo. After correctly installed (see Spring Roo documentation).

After installed, create a new directory called listfiles-addon.

Enter into directory and start roo.

Then type into roo console project --topLevelPackage com.test.roo.addon --template ROO_ADDON_SIMPLE

This sequence will create a project for creating a simple addon, with all required classes.

Let's examine what have created and how a modification will be applied for creating our addon.

In directory src/main/resources/META-INF/spring two files are present, log4j.properties and applicationContext.xml. applicationContext file is a Spring configuration file that configure Spring for work with annotations (@Configurable, @Component, ....).

First class to take a look:


src/main/java/com/test/roo/addon/PropertyName.java

This class represents attributes of options of our command. For example, logger addon, the command is logging setup and then --level is the option, and that option has many attributes (FATAL, ERROR ...), these attributes are what are defined in this class. Must implements Comparable.

Let's take a look of important points:

private String propertyName; [1]

public static final PropertyName USERNAME = new PropertyName("Username"); [2]
public static final PropertyName HOME_DIRECTORY = new PropertyName("Home Directory");

private PropertyName(String propertyName) { [3]
Assert.hasText(propertyName, "Property name required");
this.propertyName = propertyName;
}

public String getPropertyName() {
return propertyName;
}

public final boolean equals(Object obj) {
return obj != null && obj instanceof PropertyName && this.compareTo((PropertyName) obj) == 0;
}

public final int compareTo(PropertyName o) { [4]
if (o == null)
return -1;
int result = this.propertyName.compareTo(o.propertyName);

return result;
}

public final String getKey() { [5]
return this.propertyName;
}


[1]: Property name. This value will be used in our Command class, for now, imagine as a key that is unique.
[2]: A list of public static final attributes must be defined. Their type must be the same of class we are implementing, and their name will be used for autocompletation. In case of logger addon (FATAL, ERROR, INFO, ...).
[3]: Good practice to generate constructor as private in this kind of classes.
[4]: Class must implements compareTo. Because our key (propertyName) is unique, this attribute is used, and as usually equals is also implemented using compareTo.
[5]: Method that must returns the key (propertyName). Must be called getKey()

Next important class:

src/main/java/com/test/roo/addon/Commands.java

This class represents the command, and what options accept. This class must implement CommandMarker.

Let's take a look of important points:

@ScopeDevelopmentShell [1]
public class Commands implements CommandMarker {

private static Logger logger = Logger.getLogger(Commands.class.getName());

private Operations operations; [2]

public Commands(StaticFieldConverter staticFieldConverter, Operations operations) { [3]
Assert.notNull(staticFieldConverter, "Static field converter required");
Assert.notNull(operations, "Operations object required");
staticFieldConverter.add(PropertyName.class);
this.operations = operations;
logger.warning("Loaded " + Commands.class.getName() + "; try the 'welcome' commands");
}

@CliAvailabilityIndicator("welcome property") [4]
public boolean isPropertyAvailable() {
return true; // it's safe to always see the properties we expose
}

@CliCommand(value="welcome property", help="Obtains a pre-defined system property") [5]
public String property(@CliOption(key="name", mandatory=false, specifiedDefaultValue="USERNAME", unspecifiedDefaultValue="USERNAME", help="The property name you'd like to display") PropertyName propertyName) [6] {
return operations.getProperty(propertyName); [7]
}

....


[1]: Annotation for registering Command with automatic classpath scan.
[2]: Can be called the Business Object of our Command object. Contains logic of command, options and attributes.
[3]: Constructor, with two arguments, first of all StaticFieldConverter, which will be used for registering our previous, attributes class. (PropertyName.class). The second one is the business object class.
[4]: Annotates a method that can indicate whether a particular command is presently available or not. The string represents the name of the command or commands that this availability indicator represents.
[5]: Annotates a method indicating which method must be called when the command have to execute. value attribute is the name of the command (what user must enter), in case of logging is logging setup, and help attribute that shows the message when help is required.
[6]: Each option is annotated with CliOption. This method can contain as many CliOption annotations as required. Of all annotation attributes, one is so important, key. The attribute value must be the same as returned in getKey() function of PropertyName.class. Another important thing, look the METHOD attribute, it is our attribute class defined before. Spring Roo will inject the static final instance chosen by user.
[7]: Calling business object.

Last important class is:

src/main/java/com/test/roo/addon/Operations.java

This plain annotated class, is responsible of implementing command logic. Because of annotation, spring-roo can use constructor inject for providing some specific type instances. Those classes can be FileManager, PathResolver, MetadataService, ProjectOperations, ... Zero or more of these classes can be used in constructor. Let's take generated class as example:

@ScopeDevelopment [1]
public class Operations {

private static Logger logger = Logger.getLogger(Operations.class.getName());

private FileManager fileManager;
private MetadataService metadataService;

public Operations(FileManager fileManager, MetadataService metadataService) { [2]
Assert.notNull(fileManager, "File manager required");
Assert.notNull(metadataService, "Metadata service required");
this.fileManager = fileManager;
this.metadataService = metadataService;
}

public String getProperty(PropertyName propertyName) { [3]
Assert.notNull(propertyName, "Property name required");
String internalName = "user.name";
if (PropertyName.HOME_DIRECTORY.equals(propertyName)) {
internalName = "user.home";
}
return propertyName.getPropertyName() + " : " + System.getProperty(internalName);
}


[1]: Annotation used by Spring-Roo.
[2]: Constructor only using two spring-roo classes. FileManager and MetadataService, both of them will be injected by spring-roo.
[3]: Business Method called by Command class.

Another example could be LoggingOperations. That's the class used by logging addon.

LoggingOperations(FileManager fileManager, PathResolver pathResolver, MetadataService metadataService) where other class rather than used in our exmaple, is passed, PathResolver.

Now I am going to explain what is the purpose of most used injected classes in Operations class.

- FileManager, used for modifying the underlying disk storage. Can be used for scanning directories, create files, directories, delete, ...
- PathResolver, is primary mechanism to resolve paths.
- MetadataService is used for returnig metadata information. Usually used as
ProjectMetadata projectMetadata = (ProjectMetadata) metadataService.get(ProjectMetadata.getProjectIdentifier());
and ProjectMetadata offers convenience methods for acquiring the project name, top level project package name, registered dependencies and path name resolution services.
- ProjectOperations provides common project operations, such as adding dependencies, update project type, ...

And as an overview, that's all. Finally perform assembly command is executed and we have our addon ready.

Final step move generated jar to $ROO_HOME/dist and restart roo.

In next entries I will write how to modify applicationContext, generate specific files, ITD, …

martes, marzo 09, 2010

QR

Today I have found one really useful link for generating QR codes from any text. The link is http://invx.com/. If you look closely you will find a "REST" url for generating QR files from your application. Link is http://invx.com/code/?code=YOUR+TEXT in UTF-8.

jueves, marzo 04, 2010

.. she spends her last dollar for a bottle of vodka for tonight ...



Drink a Mojito and leave EasyMock. In some conferences I have been recently, I have discovered that most people in unitary tests, use EasyMock for stubbing and mocking. And I am wondering, why? Mockito offers, from my point of view, the same features that EasyMock, but better readability and simplified.

Take a look of next example:

In EasyMock:


import static org.easymock.classextension.EasyMock.*;

List mock = createNiceMock(List.class);

expect(mock.get(0)).andStubReturn("one");
expect(mock.get(1)).andStubReturn("two");
mock.clear();

replay(mock);
someCodeThatInteractsWithMock();

verify(mock);


And with Mockito the same code:


import static org.mockito.Mockito.*;

List mock = mock(List.class);

when(mock.get(0)).thenReturn("one");
when(mock.get(1)).thenReturn("two");

someCodeThatInteractsWithMock();

verify(mock).clear();


In http://mockito.googlecode.com/svn/tags/latest/javadoc/org/mockito/Mockito.html anyone can see Mockito documentation and tutorial, but what I am going to explain is how Mockito help me writing better tests.

First of all, I use Mockito for stubbing classes (Business Objects). In always use Design By Interfaces approach. This approach in conjunction with Spring Framework (IoC), makes my software so modular and reusable, and as you will see soon, testable too.

Imagine we are creating a piece of software that uploads an image in FTP server. We would have an interface called FTPService with a method called int upload(String serverDirectoryPath, String filenamePath) throws NotEnoughSpaceException.

This method would upload a file to given server directory, returning the number of written bytes, and if server is full, NotEnoughSpaceException is thrown; and its implementation called FTPServiceImpl.

Moreover we would have a business object, which will act as a controller of all procedures related with uploading a file (check if uploading file exists, establishing connection, closing connection ...). This class would have a FTPService setter for injecting the implementation (in our case FTPServiceImpl).

Ok, we have got the scenario, now we start playing with Mockito.

As you can see, first problem for testing our business object is that we require a ftp server and/or network connection, but, wait, we are writing unit tests, not integration tests, so a strategy for testing controller without a server is required. And here comes stubbing and Mockito. A stub may simulate the behavior of existing code (such as a procedure on a remote machine) or be a temporary substitute for yet-to-be-developed code. And creating a stub with mockito is as simple as:

(test class)

import static org.mockito.Mockito.*;

....

ControllerBOImpl controller = new ControllerBOImpl();

//Create Mock
FTPService mockedFtp = mock(FTPService.class);

//stubbing. When upload method with "serverPath" as first argument and "filePath" as
//second argument, 1234 integer will be returned.

when(mockedFtp.upload("serverPath", "filePath")).thenReturn(1234);

//inject mock to ControllerBO
controller.setFTPService(mockedFtp);

//Now we can start testing ControllerBOImpl as a FTP Server was present.
int writtenBytes = controller.uploadFile("serverPath", "filePath");
....


Of course more steps would be required in previous example like stubbing more methods of FTPService or writing asserts for ControllerBOImpl. But I think that would be information that distracts reader from what is really important. Stubbing with Mockito is so easy.

As you have noted, when you stub something that has attributes, you must provide hardcoded values, and that values must be used in method calling. It is not the same calls controller.uploadFile("serverPath", "filePath") than controller.uploadFile("directory",”filePath") because attribute values are different.

To avoid that, hamcrest http://code.google.com/p/hamcrest/ appear on screen.


Second reason why I use Mockito. I can also use Hamcrest. Following previous example would not use the expression:

when(mockedFtp.upload("serverPath", "filePath")).thenReturn(1234);

but:

when(mockedFtp.upload(anyString(), anyString())).thenReturn(1234);


More flexible solution, any string will act in the same way. See http://mockito.googlecode.com/svn/tags/latest/javadoc/org/mockito/Mockito.html#3 for more examples about argument matchers.

Third reason. I can mock for returning exceptions.

Previous example throws an exception when hard disk becomes full. But how can I test that!!! If I can't upload a file that its size must be 500Gb or more!!!.

No problem with Mockito, I write down another test, but changing one line:

from

when(mockedFtp.upload(anyString(), anyString())).thenReturn(1234);

to

when(mockedFtp.upload(anyString(), anyString())).thenThrow(new NotEnoughSpaceException());


Easy to test that complicated and rare situation.

Fourth Reason. Mockito allow stubbing void methods.

Stubbing voids requires different approach from when(Object) because the compiler does not like void methods inside brackets.

There are four possible solutions, but I only use two of them. doThrow(Throwable) when I want to test a void method throwing an exception, and doNothing() [default behavior], when no interaction is required.

FTPService would also have a method for connecting to server, maybe called connect()throws IOException() and would throw an exception when could not establish a connection.

Two tests are required for testing that these functionalities:

First Test:

doNothing().when(mockedFtp).connect();

And Second one:

doThrow(new IOException()).when(mockedFtp).connect();


And finally, and this reason applies only people who write tests using BDD approach. In summary, means write test with follow structure, //given //when //then comments as fundamental parts of test methods.

Remember that Mockito uses when method for “record” behavior? Well, in BDD approach, when paragraph is used for calling the business method. Note that when does not fit nicely into BDD, because given paragraph is what is called when in Mockito. For that reason Mockito provides a BDDmockito class. This class changes when method name for given method name. Thanks of that, our test is more readable and follows BDD standard.

So my test in BDD would look like:

import static org.mockito.BDDMockito.*;

…..
ControllerBOImpl controller = new ControllerBOImpl();

//Create Mock
FTPService mockedFtp = mock(FTPService.class);
//Given
given(mockedFtp.upload(anyString(), anyString())).willReturn(1234);

//When
int size = controller.uploadFile("serverPath", "filePath");

//Then
assertEquals(1234, size);



And these are the four reasons why I am using Mockito, in summary because it is simpler than EasyMock, more readable and easy to use.

jueves, febrero 25, 2010

Time waits for nobody

Yesterday I discovered a new library based on Joda Time and JDK 5 Time, called DateCalc (objectlabkit) http://objectlabkit.sourceforge.net/

This library is useful when our application must deal with holidays and what to do when a calculated day falls on a holiday or weekend.

Imagine next use case:
- Employees have to say how many days of vacation will enjoy from one date. System must notify when employees are at office.

Assume that employee says that he will start his vacations on 22/02/2010 and will be 6 days out of office. So in theory our employee will be at office on 28th day of same month (22 + 6). But looking at calendar, one will see that he won't be there on 28 because it is Sunday (assuming that weekends are Saturday and Sunday). In fact he will be at office on 1/03/2010 (Monday).


This use case can be focused with two approaches:

1) Using java.util.Calendar class, and then the holidays and weekends problem must be controlled by our program. Calculating “what day our employee returns to office” is not only a matter of calling Calendar.add function.

2) Using DateCalc library which watch out for us.

Not only think about weekends and summer holidays, but national holidays like 4th of July in case of USA.

Take a look to its website, there you can find examples and algorithms for handling holiday problem