Book Review: Soft Skills: The software developer's life manual by John Sonmez

Rating: 9/10

The title of “Soft Skills” suggested to me that this book might be about all the non-technical skills you need to get along at work and with your colleagues. But to my surprise, and to my delight, it turned out to be much more than that. The subtitle of “The software developer’s life manual” is much more apt, as this book lays out a collection of suggestions for you, the software developer, to get the best out of your career and the rewards that come with it.

John starts by outlining the broad choices you have in terms of what type of career you can choose to have. Perhaps you’re happy working as an employee of a company, or contracting or freelancing, or maybe you have a burning desire to be an entrepreneur and want to make it as master of your own venture. The pros and cons of each of these career choices are explored in a refreshingly straight forward manner. Subsequent chapters go on to explore each of these in much more detail, which certainly gave me a good deal of food for thought about my own career journey.

Some really solid suggestions are presented around the idea of creating a brand for yourself. How to get yourself and your talents known to your peers and turn the tables of your career. No longer will you be the one searching for new jobs, new jobs will be searching for you instead. That’s a powerful position to find yourself in. Nothing discussed is beyond the reach of anyone with an ounce of dedication.

This is where the book ventured into unexpected territory. A great deal of time is spent discussing the options that a person has to make sound investments with the money earned from their software development career. Suggestions such as salary negotiations, Options trading, real estate investment, and planning your retirement. Life is much more than a pay-cheque.

The last sections are all about personal health, fitness, and relationships. A proposal to break the stereotype of the lone nerd living on pizza and caffeine by putting forth a set of very achievable things to break the cycle. Wrapping up with arguably the most important topic of all, relationships. As a happily married man who is relatively fit and healthy I skimmed over these sections a little but the general advice looked sound enough to me.

Normally it takes me a few weeks to read a book of this size, but in this case I flew through it in one week flat and I found every opportunity to read ‘just one more chapter’. A really good compelling read that I will be recommending to my fellow developer friends.

I’m writing tests for a class and the class has a dependency on a static call but I don’t want to include that dependency in the scope of my test. What do I do? With a static dependency I have limited choices, the most well known of which is to use PowerMock. However, I find introducing PowerMock into my test cases adds a lot of chaff that I don’t like because it can hide the true nature of the test.

Thankfully there are other options. I’ll explore one of them here.

I have a class that looks like this:

public class EnthusiasmGuage {

    public String howEnthused() {
        switch (Today.whatDayIsIt()) {
            case "Monday": return "Moderate";
            case "Tuesday": return "Good";
            case "Wednesday": return "Good";
            case "Thursday": return "Moderate";
            case "Friday": return "Low";
            case "Saturday": return "Epic";
            case "Sunday": return "Epic";
            default: return "Erm, what?";
        }
    }
}

The tricky part of testing this method is that the call to Today.whatDayIsIt() is static. I don’t want to include that method in my tests because, well it could be for a number of reasons but let’s just say that including it is a bad idea. Besides, all I want to do is verify that the howEnthused() method returns "Epic" on a Saturday. I need to get the behaviour of Today.whatDayIsIt() under my control.

Here’s how.

I wrap the static call to Today.whatDayIsIt() in an instance class, inject the wrapper class into the class under test, then use my normal tools to replace the instance class with a test double or mock.

public class EnthusiasmGuage {

    private TodayWrapper todayWrapper;

    public EnthusiasmGuage() {
        todayWrapper = new TodayWrapper();
    }

    public EnthusiasmGuage(TodayWrapper todayWrapper) {
        this.todayWrapper = todayWrapper;
    }

    public String howEnthused() {
        switch (todayWrapper.whatDayIsIt()) {
            case "Monday": return "Moderate";
            case "Tuesday": return "Good";
            case "Wednesday": return "Good";
            case "Thursday": return "Moderate";
            case "Friday": return "Low";
            case "Saturday": return "Epic";
            case "Sunday": return "Epic";
            default: return "Erm, what?";
        }
    }
}

The wrapper class simply delegates on to the static call. The functionality has not changed.

public class TodayWrapper {

    public String whatDayIsIt() {
        return Today.whatDayIsIt();
    }
}

OK good, but now what. I can now replace the wrapper with a test double where I have the ability to set the day at runtime. Because this fake version is only for use within this test case I can declare it as a private inner class of the test itself.

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.*;

public class EnthusiasmGuageTest {

    @Test
    public void whenSaturday_enthusiasmEpic() {
        SetDayTodayWrapper todayWrapper = new SetDayTodayWrapper("Saturday");

        EnthusiasmGuage enthusiasmGuage = new EnthusiasmGuage(todayWrapper);

        assertThat(enthusiasmGuage.howEnthused(), is("Epic"));
    }

    private class SetDayTodayWrapper extends TodayWrapper {
        private String dayToday;

        public SetDayTodayWrapper(String dayToday) {
            this.dayToday = dayToday;
        }

        @Override
        public String whatDayIsIt() {
            return dayToday;
        }
    }
}

That’s it. I’ve tested my EnthusiasmGuage class without resorting to using PowerMock or any other Reflection based wizardry.

I write Java for a living. I’m familiar with classes having state. For example:

public class EchoService {
    private Map<String, String> messages = new HashMap<>();

    public String getMessageForKey(String key) {
        return message.get(key);
    }

    public void setMessageForKey(String key, String message) {
        messages.put(key, message);
    }
}

How can I achieve something similar in Clojure? Perhaps defining a map (def messages {})? No, that won’t work because a def is immutable so I can’t add any elements to it. The good new is that I can use an atom.

What’s an Atom?

An Atom is a reference to something. That something can be any type of value, in this it refers to a map.

(def messages (atom {}))

deref

You can ask at atom to give you the value it refers to using deref

(deref ref)
(deref ref timeout-ms timeout-val)

Example

(deref messages)

swap!

Most importantly, for the purposes of this exercise, by using swap! I can apply a function to the value it refers to then have it refer to the result of that function.

(swap! atom f)
(swap! atom f x)
(swap! atom f x y)
(swap! atom f x y & args)

Example

(swap! messages assoc "key" "val")

The atom messages now refers to the map {"key" "val"}.

Putting it all together

Writing the equivalent of that Java code in Clojure

(def messages (atom {}))

(defn get-message-for-key [key]
    (key (deref messages))
)

(defn set-message-for-key [key val]
    (swap! messages assoc key val)
)

TDD is Specifying, not Testing

I’ve been practicing TDD for a little while now and it has made a huge difference to the way I work. Not from the outside, I still get stuff done, I still swear at the computer (a lot), and I still make mistakes (also a lot). But from the inside, things are much calmer and I feel much more in control of my workflow. Most valuably I know when I’m done.

However. There’s a conversation I have with myself from time to time, and it goes a little like this:

“OK, so I have to implement x, and x has to do y”

“Fine. I’ll write a test for that”

“Wait, but what am I testing? There’s nothing there yet. How I can I be testing if there’s nothing there to test? It doesn’t make sense.”

“So what am I doing? It feels more like I’m writing a specification for something I haven’t done yet. Yes, that sounds better.”

And then I get on with it. A bit worried that I’m talking to myself.

The traditional TDD mantra is “Test -> Code -> Refactor”. I like this, and I have a sticky note next to my monitor with that scribbled on it in an attempt to keep me right. But I’m going to change it to a new mantra: “Specify -> Satisfy -> Refactor”. The practice is the same but the changed semantics remind me what it is that I’m actually doing. Which is defining the specification up front in a way that will automatically verify whether my implementation satisfies it. I repeat this cycle until I can’t think of any more things it should, or shouldn’t, do. Then I stop. I’m done. Walk away. Move on.

But don’t forget to refactor. Never forget to refactor.

A final thought. Since practicing TDD I have noticed something very interesting. I still make mistakes, and I will continue to do so. But the nature of my mistakes have changed from:

“It’s doing what? It’s not supposed to do that! I don’t have a good feeling about this!”

to

“Oh you wanted it to do that? I thought you wanted it to do this. OK, I’ll update the spec and change the code. No problem”

So away I go, update the specification code, change the implementing code to satisfy it.

Stop. I’m done. Walk away. Move on.

Have you ever had a method that looks like this, where the overvable output is a static call to System.out.println(), and wondered how to test it?

public class NameCaller {

    public void nice(String name) {
        System.out.println("Hello " + name + ", nice to see you.");
    }

    public void nasty(String name) {
        System.out.println("Ugh, not " + name + " again.");
    }
}

You want to verify that when you pass in the String “Tim” to the nice() method you get “Hello Tim, nice to see you.” printed to the terminal. But, how the heck do you sense what’s being printed to the terminal?

Here’s how.

Wrap the calls to System.out in an instance class, inject the wrapper class into the class under test, then use a class mocking test tool to capture the output. For example with jUnit and Mockito:

public class NameCaller {
    private SystemOutWrapper systemOut = new SystemOutWrapper();

    public NameCaller() {}

    public NameCaller(SystemOutWrapper systemOut) {
        this.systemOut = systemOut
    }

    public void nice(String name) {
        systemOut.println("Hello " + name + ", nice to see you.");
    }

    public void nasty(String name) {
        systemOut.println("Ugh, not " + name + " again.");
    }
}
public class SystemOutWrapper {
    public void println(String output) {
        System.out.println(output);
    }
}
public class NameCallerTest {
    private SystemOutWrapper systemOut;
    private NameCaller nameCaller;

    @Before
    public void setUp() {
        systemOut = mock(SystemOutWrapper.class);
        nameCaller = new NameCaller(systemOut);
    }

    @Test
    public void nice_givenName_shouldPrintNiceMessage() {
        nameCaller.nice("Tim");
        verify(systemOut).println("Hello Tim, nice to see you.");
    }

    @Test
    public void nasty_givenName_shouldPrintNastyMessage() {
        nameCaller.nasty("John");
        verify(systemOut).println("Ugh, not John again.");
    }
}

You can employ this general technique to observe calls to static methods in any class.