Testing in Java: Part II – Writing a Fake

In the first part we talked about the domain objects and how to test a domain object.  Now it’s time to look at how to persist them to an in-memory data store for testing purposes.  We’ll be writing this in such a way that at a later date you can replace the in-memory representation with a strategy that persists the data to disk.  So, let’s jump right into the code starting with the data access object interface.

package com.laneholloway.unittestingexample.database.dao;

import com.laneholloway.unittestingexample.domain.MyItem;

import java.util.UUID;

/**
 * A simple Data Access Object
 */
public interface MyDao {
    public boolean exists(UUID guid);
    public MyItem get(UUID guid);
    public boolean save(MyItem item);
    public void delete(UUID guid);
}

Looking at the code you can easily tell that there are some simple CRUD operations and an exists command. Any datasource that we want to write the data to must implement these commands and inside the program, we should only use these commands to interact with the object. In order to facilitate the testing of the framework, I’ve created a simple in memory dao and placed it into the test directory that maven creates.

package com.laneholloway.unittestingexample.database.dao;

import com.laneholloway.unittestingexample.domain.MyItem;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * An in-memory representation of a datastore using MyDao
 */
public class MyInMemoryDao implements MyDao {
    private Map<UUID, MyItem> storedItems;

    public MyInMemoryDao() {
        this.storedItems = new HashMap<UUID, MyItem>();
    }

    @Override
    public boolean exists(UUID guid) {
        return this.storedItems.containsKey(guid);
    }

    @Override
    public MyItem get(UUID guid) {
        return this.storedItems.get(guid);
    }

    @Override
    public boolean save(MyItem item) {
        this.storedItems.put(item.getGuid(), item);
        return true;
    }

    @Override
    public void delete(UUID guid) {
        this.storedItems.remove(guid);
    }
}

The in memory dao uses a Map to hold the MyItem elements. As you can tell, the implementation is straight-forward and doesn’t pull any punches. It does exactly what it needs to do in order for us to test other parts of the system that require the use of the MyDao interface. In order for the other Maven modules to use this test implementation, we have to do a little work in Maven to expose this as a test class. In the POM file relating to the doa-interface module, we add this bit which creates a test jar file.

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>test-jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

Now, using this test jar we can begin to test classes that use the MyDao interface. To use this test jar you modify the POM files for all modules that need access to this code with a dependency with it’s scope set to test.

In our case, we have the MyCommonInterface class which you’ll typically see in applications to give the consumers of the code a unified API to the CRUD operations abstracting away the DAO or DAOs that might make up the data storage of the application.

package com.laneholloway.unittestingexample.database.commoninterface;

import com.laneholloway.unittestingexample.domain.MyItem;

import java.util.UUID;

/**
 * A common interface to abstract away the various DAOs and allow the consumer of the API one interface to all
 * data.
 */
public interface MyCommonInterface {
    public boolean exists(UUID guid);
    public MyItem get(UUID guid);
    public boolean save(MyItem item);
    public void delete(UUID guid);
}

I’ve also supplied a simple implementation that uses a single DAO,

package com.laneholloway.unittestingexample.database.commoninterface;

import com.laneholloway.unittestingexample.domain.MyItem;
import com.laneholloway.unittestingexample.database.dao.MyDao;

import java.util.UUID;

/**
 * A very simple common interface
 */
public class MyCommonInterfaceForOneDao implements MyCommonInterface {
    private final MyDao dao;

    public MyCommonInterfaceForOneDao(MyDao myDao) {
        this.dao = myDao;
    }

    @Override
    public boolean exists(UUID guid) {
        return this.dao.exists(guid);
    }

    @Override
    public MyItem get(UUID guid) {
        return this.dao.get(guid);
    }

    @Override
    public boolean save(MyItem item) {
        return this.dao.save(item);
    }

    @Override
    public void delete(UUID guid) {
        this.dao.delete(guid);
    }
}

You can see that in the constructor, it expects a variable of type MyDao and then uses to perform CRUD operations. In order to properly test this, we need to use the in memory implementation so we don’t have to worry about creating a database, cleaning the database, and all the other database tasks needed just to test this interface. Using the this implementation, we can create a JUnit test class like this:

package com.laneholloway.unittestingexample.database.commoninterface;

import com.laneholloway.unittestingexample.database.dao.MyDao;
import com.laneholloway.unittestingexample.database.dao.MyInMemoryDao;
import com.laneholloway.unittestingexample.domain.MyItem;
import com.laneholloway.unittestingexample.domain.MyItemImpl;
import org.junit.Before;
import org.junit.Test;

import java.util.UUID;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

public class MyCommonInterfaceForOneDaoTest {
    private MyCommonInterfaceForOneDao myCommonInterfaceForOneDao;

    @Before
    public void setup() {
        MyDao myDao = new MyInMemoryDao();
        myCommonInterfaceForOneDao = new MyCommonInterfaceForOneDao(myDao);
    }

    @Test
    public void can_save_item() throws Exception {
        MyItem myItem = new MyItemImpl(UUID.randomUUID(),"Test Item");
        myCommonInterfaceForOneDao.save(myItem);
        assertTrue(myCommonInterfaceForOneDao.exists(myItem.getGuid()));
    }

    @Test
    public void can_delete_item() throws Exception {
        MyItem myItem = new MyItemImpl(UUID.randomUUID(),"Test Item");
        myCommonInterfaceForOneDao.save(myItem);
        myCommonInterfaceForOneDao.delete(myItem.getGuid());
        assertFalse(myCommonInterfaceForOneDao.exists(myItem.getGuid()));
    }
}

In the setup method, you can see that MyInMemoryDao is initialized and then injected into the MyCommonInterfaceForOneDao constructor which then allows these simple unit tests to be run verifying the correct operations. And with this, we’ve wrapped up the second section of the code, creating a data access layer that abstracts the database away from the production code and will allow multiple implementations of the data store to be used with minimal issues.

In later articles, I’ll show how to use Spring to simplify these tests and the application itself. Next time, we’ll talk about the business logic and REST layers of the code.

If you have any comments, concerns, or updates I should make to this, let me know in the comments below.

Running command-line programs from inside Java

I’ve been writing a program for a class I’m taking at school to automate some of the work that had to be done.  I could have written it as a shell script, but I wanted to be more adventurous and write it in Java so it could be run in more than just a Unix environment.  So, as you can guess, I had to do execute the program from the command line.  Normally, you’d do this with the exec method off of the Runtime, however, this causes some problems with permissions.  The way to do execute something from the command line is to use the ProcessBuilder object and it’s dead simple.

List command = new ArrayList();
command.add("file_to_execute");
command.add("option1");
command.add("option2");

ProcessBuilder processBuilder = new ProcessBuilder(command);
Process process = processBuilder.start();

process.waitFor();

As you can tell looking at this simple example, command is a list of String which becomes the command you’d normally type into the command line interface. The processBuilder object sets all the wonderful things up to run an operating system process and when you specify start() it turns it into a Process where you can then wait for all the return value.

Of course, there is a lot more to it than just this, but for my case, all I needed was a quick and dirty command to be run and this did the trick.  You can read more about it on StackOverflow.

Testing in Java: Part I – Introduction

As I’ve alluded to, this is the first article in a series to walk through the process of testing an application for production.  We’ll be making a simple REST interface web application that connects to a back-end database.  It will do some basic CRUD operations and I’ll show how I’d test each layer of this application.  Hopefully, you’ll find some of these techniques useful and able to apply them to your own work.  You can download, fork, or view the entire code base from the GitHub repo.

A typical web application has a few tiers: user interface, business logic, and data access.  In the case of this application I’m following the same idea, but have broken out the objects that are being modified into a domain-objects package inside of the project.  This is where we’ll start this series — talking about the objects and how to test them. I’m going to break the pure TDD-style for this series and write an object first, then write a test :).

In an application where you’re dealing with objects that the user is performing a CRUD operation upon you’ll want to think about these first.  The initial design would consist of determining what each of these objects are and create an interface and class embodying those concepts.  In our case we have a simple item that consists of a name and a unique identifier.  I’ve named it: MyItem.  Below, you’ll see the interface for MyItem along with a simple default implementation, MyItemImpl.

package com.laneholloway.unittestingexample.domain;

import java.util.UUID;

public interface MyItem {
    public UUID getGuid();
    public String getName();
}
package com.laneholloway.unittestingexample.domain;

import java.util.UUID;

/**
 * A simple default implementation
 */
public class MyItemImpl implements MyItem {
    private final UUID uuid;
    private final String name;

    public MyItemImpl(String itemName) {
        this(UUID.randomUUID(), itemName);
    }

    public MyItemImpl(UUID guid, String itemName) {
        this.uuid = guid;
        this.name = itemName;
    }

    @Override
    public UUID getGuid() {
        return uuid;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public boolean equals(Object o) {
        if (o == null) return false;
        if (o instanceof MyItemImpl) {
            MyItemImpl that = (MyItemImpl) o;
            if (that.getGuid().equals(this.uuid) && that.getName().equals(this.name)) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
}

Now that we have the default implementation, we need to have a test for how we want the item to behave within the system. In our case, if the id and the name are the same, the objects are equal. If either is not equal, the objects are not equal. To verify this, we can write a test class using JUnit4. Looking at the code, you’ll notice that I’ve written two of the three tests and I’ve left the last one as an exercise (it really isn’t that hard :)).

package com.laneholloway.unittestingexample.domain;

import com.laneholloway.unittestingexample.domain.MyItem;
import com.laneholloway.unittestingexample.domain.MyItemImpl;
import org.junit.Before;
import org.junit.Test;

import java.util.UUID;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

/**
 * Simple tests to show off the MyItemImpl
 */
public class MyItemImplTest {
    private MyItem myItemOne;
    private MyItem myItemTwo;
    private MyItem myItemThree;

    @Before
    public void setup() throws Exception {
        UUID testId = UUID.randomUUID();
        myItemOne = new MyItemImpl(testId, "test");
        myItemTwo = new MyItemImpl(testId, "test");
        myItemThree = new MyItemImpl(UUID.randomUUID(), "test");
    }

    @Test
    public void if_uuid_and_name_are_the_same_items_are_the_same() throws Exception {
        assertTrue(myItemOne.equals(myItemTwo));
    }

    @Test
    public void if_uuids_are_different_the_items_are_different() throws Exception {
        assertFalse(myItemOne.equals(myItemThree));
    }
}

Now, pat yourself on the back, with these three classes you’ve created the object that is being modified by the program and tested it to make sure the implementation behaves as expected.

From here, we will examine the more complicated data access layer, then the business logic, and finally, the REST layer.

As always, if you have any comments, concerns, edits that I should make, let me know in the comments below.

Programming and chairs

Recently the handle on the back of my Humanscale Freedom chair broke and got me really annoyed.  How could a piece so small that I never touch just break the first time I use it to pull the chair?  After getting over the annoyance of broken, sharp plastic, I emailed Humanscale and they sent me a free replacement handle.  Now, you’re wondering why I’m talking about a broken handle on a chair, and I’m getting to the meat of the post.  It made me think about how important the right desk setup and chair is when you’re programming.  You’re spending over eight hours a day in this chair.  Why would you settle for something that is so uncomfortable?

Many people, have written and debated about the perfect programming chair and I think it’s a worthwhile investment.  Granted, you can’t find Herman Miller Aeron chairs for $100 like you used to during the dot com bust but a really good chair can be found for a reasonable amount.  Personally, I’m a fan of the Humanscale Freedom with a headrest.  It wasn’t the cheapest, but it is by far the best investment I’ve made in my career as a programmer.  The ability to stand up after a coding marathon and feel like you just sat down is a wonderful feeling.

If you can’t afford or don’t want to spend money on a chair, think about setting a time and getting up and moving around for 10 minutes every hour or converting your sit-down desk to a standing desk so you can at least move around a little during the work day.  Your body and your mind will thank you for it.

See some of my code on GitHub

Just a quick update, I’ve decided to publicize the fact I’m using GitHub to store all the example code I’m creating for my website articles.  You can find the links to the repositories in the articles themselves or you can just see all the things I’m working on by going to my user page on GitHub.

You’ll see the unit-testing-examples repository if you poke around my repos.  This is going to be the basis for one series of articles about unit testing, programming, and designing a simple application you’d see in production.  I don’t want to give away too much but I think the articles are going to be great. 🙂

Principles of Good Design as Applied to Software Engineering

Most people know Apple’s iconic designer, Jonathan Ives, but few have heard of another influential designer, Dieter Rams.  Dieter Rams was the chief of design at Braun from 1961 to 1995 and head of design until his retirement in 1998.  Some examples of his work include: 606 Universal Shelving System, the Braun T3 pocket radio, and the Braun T1000 radio. These are considered iconic and many of the new Apple products share more than a passing resemblance to these iconic designs.

Many industrial and user interface designers have been inspired by his work and design principles and I’ve often wondered how his ten principles for good design could be applied to software engineering and programming.  While maybe not intuitively obvious, I believe they can be applied to programming since the principles of design are always the same.  Additionally, one should never stop learning and what better way to learn than to learn something tangential to what you enjoy?  There are always universal lessons and principles that can be adapted and applied elsewhere.

Rams’ Design Principles

Rams’ design principles are simple and straight-forward and are summarized as follows:

Good design:

  • is innovative –The possibilities for innovation are not, by any means, exhausted. Technological development is always offering new opportunities for innovative design. But innovative design always develops in tandem with innovative technology, and can never be an end in itself.
  • makes a product useful –A product is bought to be used. It has to satisfy certain criteria, not only functional, but also psychological and aesthetic. Good design emphasizes the usefulness of a product whilst disregarding anything that could possibly detract from it.
  • is aesthetic –The aesthetic quality of a product is integral to its usefulness because products are used every day and have an effect on people and their well-being. Only well-executed objects can be beautiful.
  • makes a product understandable –It clarifies the product’s structure. Better still, it can make the product clearly express its function by making use of the user’s intuition. At best, it is self-explanatory.
  • is unobtrusive –Products fulfilling a purpose are like tools. They are neither decorative objects nor works of art. Their design should therefore be both neutral and restrained, to leave room for the user’s self-expression.
  • is honest –It does not make a product more innovative, powerful or valuable than it really is. It does not attempt to manipulate the consumer with promises that cannot be kept.
  • is durable –It avoids being fashionable and therefore never appears antiquated. Unlike fashionable design, it lasts many years – even in today’s throwaway society.
  • is thorough to the last detail –Nothing must be arbitrary or left to chance. Care and accuracy in the design process show respect towards the consumer.
  • is concerned with the environment –Design makes an important contribution to the preservation of the environment. It conserves resources and minimizes physical and visual pollution throughout the lifecycle of the product.
  • is as little design as possible –Less, but better – because it concentrates on the essential aspects, and the products are not burdened with non-essentials. Back to purity, back to simplicity.

 As Applied to Software Engineering…

Looking at the ten design principles, I’m sure you’re already seeing parallels between them and good software engineering.  We’ll go down the list and examine the meaning of each statement in the context of software engineering.

First, good software engineering is innovative.  At first glance, this might seem to support the idea of using the newest and freshest technology available.  However, looking at the rest of the rule, it specifies innovative technology can never be an end in itself.  It means, use the appropriate job for the tool and eschew the idea of using the newest technology if it doesn’t fit your problem.  Using an older library in a new way can be more innovative than just using the newest technology.

Secondly, good software engineering makes a product useful.  In the case of the software engineer, this is about easy-to-understand code (User Interface concerns fall more under UX/UI people although coding is involved there too).  This falls inline with many of the principles put forward by Clean Code by Bob Martin.

Good software engineering is aesthetic.  The design of the program (or programs) is clean and simple, like the codebase, it is easily understandable, contains enough abstractions to make sense and can be easily modified to encompass new requirements.  This is a tough point to understand, it’s hard to know when the proper amount of abstraction has been reached or know what is easily understood by others.  A few point to think about are, is the design simple?  Are you using queues instead of actors, data instead of syntax, and polymorphism instead of inheritance, switching, or matching?  Have you pulled apart the design to the base components?  Can you easily describe each part of the system?  Can you extend the design by simply removing one or two components and replace them with two or three new ones?

It makes a product understandable.  A follow on to the second and third points, the design and codebase of the program can be grokked by a new developer with little effort.  This isn’t to say it is going to be some work to look through the codebase, but it should be obvious how all the modules interact.  As a software developer, you should aim for simplicity — and note: simplicity does not mean easy :).

Good software engineering is unobtrusive.  Again, another principle of Clean Code, the codebase and design does exactly what it needs to do, no more no less, yet has the ability to be modified and integrated within another project easily and simply.  This leads to question of “how do we know the system can be modified easily and simply?”  If it isn’t, how do we fix that? And, does it mean a programmer new to the project can understand the code?  Unfortunately, this is a very interesting problem and deserves an article all to itself, but let me touch on this quickly.  In my opinion, a system can be modified easily when there are distinct breaks in modules in the code defined by interfaces that allow for good unit testing of each module proving the system is not overly coupled.

It should be honest.  Write and design simple to understand and modify code.  Consider everyone who is going to be working in the codebase, everyone should be able to understand, extend, and fix bugs within the code and adjust the architecture.  I’m not advocating a cowboy coder to come in and do a large refactor (e.g. rewrite) because in their mind it is cleaner, but again, it should be at the right abstraction at all points.  It also relates to the idea of unobtrusiveness with knowing when code is easily modifiable.

It is durable.  It uses the best tool for the job at hand; advocating code reuse and proven projects versus reinventing the wheel.  It means eschewing technologies not completely tested for your situation, opting instead for proven technologies and methodologies.  It means extending proven technologies where needed and using ideas from the bleeding edge, to make a quality product meant to last.

Thorough to the last detail.  The software’s design is meant for stability and ease of extension. The code base is well thought out and easy to understand.  The unit tests, functional tests, and integration tests express all (or as close to all) issues that can occur at the each abstraction layer.  There is sufficient documentation to understand, deploy, and modify the software.

Is concerned with the (computing) environment.  There are no memory leaks (yes, you can still have them in managed memory languages!), the algorithms are as efficient as possible for their purpose (run time vs. memory) and care is taken not to use too many resources.  The code itself is clean, straight-forward, and easy to understand.  This does not mean to go prematurely optimize and read all the papers on new, hot data structures, but it means to make good rational choice that can be explained and understood as a starting point.  As learn more about the problem and have integration testing and testing on the environment, you can begin to focus on the areas of code that need to optimized and understood better for a faster or more elegant solution.

Is as little design as possible.  As has been brought up in earlier points, the design focuses on the specifications, not the “what could happen” or “wouldn’t be cool if…” questions.  The problem is solved and designed in an elegant and easy-to-undersand way.  The code reflects this by being easy to read, understand, and modify.  You can think of this as, not being overly complicated when it comes to designing classes and methods.  Don’t use an enormous amount of variables unless you need them.

Conclusion

Good design principles can be applied anywhere design is used.  The definitions that Rams’ used were obviously questions he asked himself about his products, but it illustrates a point not laid out in his principles of good design:  you must constantly question yourself, your process, and of course, your design and implementation.

Additional Notes

I noticed multiple people have written about Rams’ design principles as they apply to software as well, you can read their articles here, here.  A wonderful talk about simplicity in design by Rich Hickey can be watched here (you really should watch it).

Additionally, I stayed away from a lot of questions that can come up. I know I didn’t touch on the idea of the right solution versus the correct solution which I’ve talked about a little before.  Also, I didn’t talk about what happens if you have conflicts between teammates on if you believe your implementation is good and they don’t, or even if your idea for the design of the software is different than someone else on your team.  These are all topics I’d love to talk about but they really deserve their own posts where we can delve into them in detail.

If you like, dislike, or have anything to say about the article, let me know in the comments below!