Thursday, June 25, 2009

Programmer Confidence and Arrogance

At SpeakerConf 2009, one of the speaker's wives asked me: Why is it that most speakers are confident, and some are simply arrogant. The question was also in the context of "software is nerdy, how can you speakers be so cocky". I pondered for a minute and replied: When no one knows what's "correct", people with confidence generally win the discussion.

Imagine the early days of medicine. Three different doctors give you three different surgery options. There's not enough experience in the industry to show which is the correct choice. Who do you trust? Probably the doctor who managed to be the most confident without being overly aggressive or cocky.

As I've said before, we're still figuring this stuff out. I constantly try to improve my processes for delivering software. I share those processes via speaking and blogging. However, I'm definitely aware that I could be doing it entirely wrong.

In general, I'm weary of developers who speak in absolutes. Most solutions I've seen are contextual, and even in context they tend to be fragile. We simply don't have the heuristics to determine what true best practices (for our field) are.

When pondering the original question I remembered when I wrote about Despised Software Luminaries. At the time I blamed passion; however, I'm guessing confidence and arrogance probably also weigh heavily on the source of animosity.

There's a direct correlation between being a luminary and your compensation package. Therefore, luminaries are enticed to gain as much market share as possible. Your luminary status is determined by the speed at which your ideas are adopted. And, without absolute proof of correctness, the speed at which your ideas are adopted can largely based on your confidence. I'm sure some luminaries see this situation and walk the line between confidence and arrogance.

Of course, not all luminaries are in it for compensation. I truly doubt Martin Fowler does what he does for money. But, the people who are looking to take market share from Martin may be motivated by a compensation package. Therefore, it's pretty hard to escape the the effects of confidence and arrogance.

The confidence and arrogance discussion is also interesting if you've ever met a luminary who you found to be completely incompetent. Perhaps they truly don't know what they were talking about, and they've just been confident enough to fool the majority of people they've met so far.

Wednesday, June 24, 2009

Java: Method Chain with Snippet

I've noticed a pattern pop up a few times in my Java code in the past 6 months. Maybe it's a decent pattern, or maybe I only have a hammer.

The problem I'm trying to solve is setting some global state, running a test, and ensuring that the global state is set back to it's original (or correct) value. My usual solution to this problem is to remove global state, but not all global states are created equally. The two global states I've been unsuccessful at removing are the current time and system properties.

In my previous post I described how I freeze time using the Joda library. The example code for freezing time was the first time I used a Method Chain with a Snippet. At the time I thought it was an ugly solution, but the best I could come up with.

A few months later I was testing some code that set and read from the system properties. My first tests set the properties and didn't clean up after themselves. This quickly caused trouble, and I found myself turning to Method Chain with Snippet again.

Here's some example code where I verify that setupDir doesn't overwrite a default property:

@Test
public void shouldNotOverrideDir() {
new Temporarily().setProperty("a.dir", "was.preset").when(new Snippet() {{
new Main().setupDir();
assertEquals("was.preset", System.getProperty("a.dir"));
}});
}

And, here's the code for the Temporarily class

public class Temporarily {
private Map properties = new HashMap();

public void when(Snippet snippet) {
for (Map.Entry entry : properties.entrySet()) {
System.setProperty(entry.getKey(), entry.getValue());
}
}

public Temporarily setProperty(String propertyName, String propertyValue) {
if (System.getProperty(propertyName) != null) {
properties.put(propertyName, System.getProperty(propertyName));
}
System.setProperty(propertyName, propertyValue);
return this;
}
}

The code works by setting the desired state for the test, chaining the state cleanup method, and passing the test code as a Snippet to the state cleanup method. The code exploits the fact that Java will execute the first method, then the argument to the chained method, then the chained method.

For the previous example, the 'setProperty' method is executed, then the Snippet is constructed and the initializer is immediately executed, then the 'when' method is executed. The Snippet argument isn't used within the when method; therefore, no state needs to be captured in the Snippet's initializer.

This pattern seems to work well whenever you need to set some state before and after a test runs. However, as I previously mentioned, it's much better if you can simply remove the state dependency from your test.

Tuesday, June 23, 2009

Freezing Joda Time

Once upon a time Mark Needham wrote about freezing Joda Time. Mark gives all the important details for freezing time (which is often helpful for testing), but I came up with some additional code that I like to add on top of his example.

Two things bother me about Mark's example. First of all, I always like the last line of my test to be the assertion. It's not a law, but it is a guideline I like to follow. Secondly, I don't like having to remember that I need to reset the time back to following the system clock.

I came up with the following idea. It's definitely a poor man's closure, but it does the job for me.
    
@Test
public void shouldFreezeTime() {
Freeze.timeAt("2008-09-04").thawAfter(new Snippet() {{
assertEquals(new DateTime(2008, 9, 4, 1, 0, 0, 0), new DateTime());
}});
}

The Freeze class is very simple:

public class Freeze {

public static Freeze timeAt(String dateTimeString) {
DateTimeUtils.setCurrentMillisFixed(JodaDateTime.create(dateTimeString).getMillis());
return new Freeze();
}

public void thawAfter(Snippet snippet) {
DateTimeUtils.setCurrentMillisSystem();
}
}

The Snippet class is even more simple:

public class Snippet {}

Using this code I can keep my assertions as close to the end of the test method as possible, and it's not possible to forget to reset the time back to the system clock.

Wednesday, June 10, 2009

Developer Testing: Welcome to the Beta Test

In March of 2009 I gave a talk at SpeakerConf about developer testing. The presentation is available as 'desktop' and 'iPhone' m4v files.Unfortunately, the Q&A session is inaudible, so I cut the end short.

Monday, June 08, 2009

Mockito non-hamcrest any matcher

These days I'm using Mockito for my behavior based tests. I like Mockito's integration with Hamcrest, but I don't always like the viral matcher requirement. In particular, if I have a method that takes 3 arguments, I don't like the fact that if I use a matcher for one argument I have to use a matcher for all 3. For example, in the following verification I don't care about the callback instance, but I do care about the timeout and the async flag.

verify(channel).subscribe(any(Callback.class), eq(100), eq(true))

I was toying with some code the other day and it occurred to me that I should be able to write my own any method that achieves what I'm looking for without requiring my other arguments to be matchers.

The code below is what I've started using as an alternative.

    public static  T any(final Class clazz) {
MethodInterceptor advice = new MethodInterceptor() {
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
if (method.getName().equals("equals")) {
return clazz.isInstance(obj);
}
return null;
}
};

return new ProxyCreator().imposterise(advice, clazz);
}

Using my any implementation the first example code can be written like the example below.

verify(channel).subscribe(any(Callback.class), 100, true)

My implementation relies on classes from cglib and spruice; however, you could copy the necessary class from spruice very easily. Here are the referenced classes:
  • net.sf.cglib.proxy.MethodInterceptor
  • net.sf.cglib.proxy.MethodProxy
  • org.spruice.proxy.ProxyCreator
There may be limitations of this implemenation, but it's been working fine for me. Please let me know if you spot a potential improvement.