Book review: Sujoy Acharya – Mockito essentials

A few weeks back I was contacted by Packt Publishing to review a relatively newly published book: Mockito essentials. Without any further talk, let’s see:

I tried to read the book like I had never seen Mockito, or encountered any of the principles of mocking before. Under these conditions some of the chapters were very useful, others less. At many points I had the impression that examples int this book are (maybe) a bit too advanced for beginners, but not so useful for pros. This is mainly because people completely new to mocking/stubbing/faking may get lost in some rather complex pieces of code, while seasoned mockers are reading more advanced books. Continue reading “Book review: Sujoy Acharya – Mockito essentials”

Advertisements

JUnit’s ExpectedException @Rule

Some time ago I had written a post about different ways to deal with exceptions using JUnit. It’s time to augment that post with a truly great way to achieve the same result.

Let’s look at this through an example. The task will be to implement a little method for an insurance company that registers a car to be insured by its license plate number. In Hungary, license plates follow the LLL-DDD pattern, where L stands for an uppercase letter, while D is a digit from 0 to 9. The initial requirement is simple: validate whether the input string conforms to the pattern described above; if it does, save it, else, throw an IllegalArgument exception. Continue reading “JUnit’s ExpectedException @Rule”

Book review: Sujoy Acharya – Mastering unit testing using Mockito and JUnit

Some weeks ago, I was contacted by Packt Publishing to write a review about the book above. Without any further introduction, let’s just jump in and see the pros and cons of this book.

Mastering unit testing using Mockito and JUnit is a pretty new book, it was published in July 2014.

Right in the first chapter, the author digs deep into the capabilities of JUnit 4. This is a very thorough analysis of the JUnit API, starting from basic things (like how to write a basic test case) and gradually moving towards more and more advanced topics (test categories, expected exceptions). Anything you’re ever going to use from JUnit is described here – and much more. While reading this chapter I had a feeling that if the reader is an expert, chances are high that they’ve already met most of those method calls and annotations; if they’re new to unit testing, then this chapter may be somewhat too fast.
Every single aspect (method, annotation etc.) is backed by some example code, but unfortunately these problems have little to do with real life applications (like assertTrue(true)). Quick note: the book uses the when_something_then_something naming convention for tests. I like this very much, this is my favorite too, as test names become much more readable.

Chapter 2 introduces automated build tools such as maven (ant, gradle) and Jenkins. I think this is a very good idea, as nowadays such tools are compulsory for a software engineer. However, three build tools (maven, ant and gradle) described in detail (I really mean in detail: how to download and configure tehm, how to put together a simple project) is a bit too much. (I think most readers want to be true masters of unit testing, and not of different build tools. To describe the concept along with an example is awesome and would have been more than enough).

Chapter 3 is very short compared to the others. It describes the test doubles – as defined by Gerard Meszaros, which is really a prerequisite to mocking. Many times people fail to see the difference between all the types of test doubles, so this chapter is very welcome.

Chapter 4 is all about mocking with Mockito. It again dives deep into Mockito with all its annotations, API methods and capabilities.  Although similar to Chapter 1, this chapter introduces a more complex example (manipulating stocks), through which it unfolds different aspects of Mockito. There are very nice tips in this chapter, like inline stubbing (saves a lot of code lines) or configuring mock default behaviors for mocks. I’m looking forward to putting in practice some of the ideas described here.

Chapters 5 and 6 will take you to the world of code coverage and code analysis tools. This is again, very cool idea to talk about in conjunction with unit tests. Maybe I would have liked it more right after chapter 2, so Mocito and its usage could have been one after another.

Chapters 7 and 8 are about using Mockito in real life. Chapter 7 is about testing web application, while Chapter 8 talks about testing the data tier. These, indeed are tough things to handle in real projects, so I like it very much that these chapters made it into the book. However, I think there is a slight focus loss here; these two chapters shouldn’t put that much attention on Spring (MVC and JDBC Template), but rather on general, technology independent problems. Sometimes  I felt like I was reading a book on Spring, with some unit testing and not the other way around.

My favorite parts were the last two chapters. Chapter 9 talks about problems that pop up every single day while fighting huge legacy code bases. Those things described there happen exactly as presented – I encountered almost each and every of them when I was a maintenance guy. The book offers practical solutions on how to overcome these obstacles and get legacy code base under test. This chapter is an awesome one, everybody should know and practice those tricks.

Chapter 10 is about best practices when it comes to unit testing. This chapter is really for the inexperienced, who have just  met unit testing but are not familiar with all the good practices about the framework. This chapter should be a very good starting point for junior programmers at the beginning of their career.

Summary.
Mastering unit testing using Mockito and JUnit has got pretty cool tips and tricks, very thorough analysis of the frameworks and practical applications for everybody out there. One thing I particularly liked is that the book offers a very good overview on all the different reasons why a piece of code becomes hard to test. Nevertheless, I can’t really figure out who is this book for. It is too fast paced for absolute beginners, but somewhat too obvious for experienced engineers – in my honest opinion, some parts may miss the targeted audience.

Having said all these, I’m rating this book 3 out of 5.

Composite Design Pattern Kata

Today’s post is nothing elevated, just two examples from which one can understand this powerful design pattern.

First, let’s do a quick recap, how the pattern actually looks like: 

(if you’re new to design patterns, please find a detailed description here)

The exercises are the following (note that the second one usually looks easier, because it’s easier to imagine. However, you are gonna have a harder time if you want to do that properly using TDD. Mocking recursive structures is not the easiest thing to do):

  1. Implement an application that can draw(no, you don’t really have to draw, just implement the data structures) pictures using rectangles and circles. A picture can be made from primitives (rectangles and circles), primitives combined with other pictures (one or more primitives and at least one other picture – which is composed of primitives), and several pictures combined. (Spoiler: circles and rectangles are leaves, pictures are composite objects)
  2. Implement an application that can compute (yes, you really have to compute) the size of a directory. The size of a directory is equal to the sum of all the files it contains plus the size of its subdirectories. (Hint: you might want to wrap java.io.File objects inside your Leaf and Composite classes. Spoiler: in this case plain files are leaves, directories are composites).

You can find a solution to the second problem here (implementation in Java, unit tested with JUnit and Mockito).

Unit testing tips and tricks

There are some common patterns when it comes to unit testing. Not very hard to solve situations, however, it might take a little time to find a solution to them, especially for the first time.

In this post I’d like to share some ideas that always pop up when someone new to unit testing joins our team. These things may seem trivial after some practicing, but still. Someone might find it useful. The code examples will be in Java, the mocking -when applicable- will be done using JMock (the same principles apply to Mockito). Continue reading “Unit testing tips and tricks”

JUnit exception handling

I was browsing through some test classes lately and saw some ways of handling exceptions in test code. It seems to me that different versions are used randomly; there is no common style, a pattern that everyone follows. So I’d like to share some good and not-so-good solutions.

In order to exemplify exception handling, I’ll use a very simple example: Let’s consider a primitive message sender, that is able to send a text message to a given IP address. The exception we are hunting for is called ExpectedException, and there’s nothing interesting about it. It’s just a simple exception:

package expectedexception;

public class ExpectedException extends Exception{

	private static final long serialVersionUID = 1L;

	public ExpectedException(String message) {
		super(message);
	}
}

Ok, so a system that sends messages to different IP addresses, huh? Then we might need something to check the validity of those addresses, it seems. (Usually I don’t write static methods, but in this case I used one for brevity):

package expectedexception;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class IPAddressValidator {

	private static final String IP_ADDRESS_STRUCTURE = "\\d{1,3}+\\.\\d{1,3}+\\.\\d{1,3}+\\.\\d{1,3}+";

	public static boolean isValidIpAddress(String ipAddress) {
		Pattern ipAddressPattern = Pattern.compile(IP_ADDRESS_STRUCTURE);
		Matcher matcher = ipAddressPattern.matcher(ipAddress);
		if (matcher.matches()) {
			return matcher.hitEnd();
		}
		return false;
	}
}

Now let’s see the message sender class. It’s code is not very complicated (note the null pointer exception when adding an element to an uninitialized list!):

package expectedexception;
import java.util.List;

public class MessageSender {

private List sentMessages;

    public void sendMessage(String ipAddress, String message) throws ExpectedException {
        if (IPAddressValidator.isValidIpAddress(ipAddress)) {
            sentMessages.add(message);
            //...
        } else {
            throw new ExpectedException("Hello world!');
        }
    }
}

The first approach we’ll be analyzing looks like:

	@Test(expected = Exception.class)
	public void shouldThrowExceptionWhenIpAddressIsNotValid() throws Exception {
		MessageSender messageSender = new MessageSender();

		messageSender.sendMessage("128.192.1.45", "Hello World");
	}

So we run the test, and get a green bar! If one is not sharp-eyed enough, will just go on and miss the point that the code is not working. The IP address is perfectly valid (it happens at copy-paste programming that someone just forgets to supply the correct parameters), so our message (Hello World) should be sent to that IP address. However, as we pointed out, there is a NullPointerException thrown inside the if statement; NullPointerException is a subclass of Exception, and as such, it perfectly satisfies the test condition. In short, should any kind of exception be thrown inside the method under test, the test case remains green. Never, never expect raw exception as result for a test case.

Ok, let’s suppose we corrected the null pointer from the example above, and so we have (note that “Ip Addres” is misspelled on purpose 🙂 ):

package expectedexception;
import java.util.List;

public class MessageSender {

	public void sendMessage(String ipAddress, String message) throws ExpectedException {
		if (IPAddressValidator.isValidIpAddress(ipAddress)) {
			//...
		} else {
			throw new ExpectedException("Ip Addres not valid");
		}
	}
}

Another approach I saw, is to write a test case that looks like:

	@Test
	public void shouldThrowExceptionWhenIpAddressIsNotValid() throws Exception {
		MessageSender messageSender = new MessageSender();

		try {
			messageSender.sendMessage("128.192.1.45.7.1", "Hello World");
		} catch (ExpectedException e) {
			assertEquals("Ip Addres not valid", e.getMessage());
		}
	}

(We fond out that the test was provided a correct parameter – e.g. valid IP address. As we are handling special cases, we just simply break that value)
Ok, this test case is a little bit better than the one before. However, it is fragile as hell. What if someone comes along and spots the misspelling? In such cases one would correct that message to “IP Address not valid”. There, the test case has just been broken! Test cases should never test exception messages. In TDD, names, messages and other stuff are refactored quite many times. I do mind correcting test cases all the time when such a refactoring is carried out. A test case should test state and/or behavior and not plain text.

Let’s move on to the next approach.

	@Test
	public void shouldThrowExceptionWhenIpAddressIsNotValid() throws Exception {
		MessageSender messageSender = new MessageSender();

		try {
			messageSender.sendMessage("128.192.1.45.7", "Hello World");
			Assert.fail("IP Address validation is broken!");
		} catch (ExpectedException e) {
		}
	}

Well this one is a little bit tricky. It calls the method under test and (as we are testing that an exception is thrown); if everything goes ok, e.g. no exception is thrown, it fails the test case. The static method fail() is part of the Assert class; optionally you can pass in a message as a parameter, so it will be displayed if the test case fails. If an exception is thrown, we are handling it with an empty catch block. The caught exception will not fail the test case, so we get a green bar. This type of construction is much more useful and less fragile then the ones above.

And finally the last one:

	@Test(expected = ExpectedException.class)
	public void shouldThrowExceptionWhenIpAddressIsNotValid() throws Exception {
		MessageSender messageSender = new MessageSender();

		messageSender.sendMessage("128.192.1.45.7", "Hello World");
	}

Simple construction, no empty catch blocks. However, you have to take extra care to expect a special enough exception class. It works exactly as the test case above, but its a much compact solution.

So pick your favorite (the third or the fourth one 🙂 ), and start using it consistently.