Friday, February 27, 2009

Mockito: Most helpful stacktrace

One of the things I have admired about the Spring framework is its helpful error messages. Yeah, of all the things I could point to, I picked that....However, work with me here. What I mean is that when things go wrong when using Spring, it spits out error messages that are full sentences that make sense and point the developer in the proper direction. None of the NoClassDefFoundError but not telling who which freaking class.

Now, I think Mockito -- the Java mocking framework -- has taken over the mantle of "King of error messages". Earlier today I had a new unit test I had just written fail. I didn't have to dig too much to find the error because Mockito pointed the way with the following stacktrace.

org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unifinished stubbing detected!
E.g. toReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
Also make sure the method is not final - you cannot stub final methods.
at
etc. etc.

How cool is that! Hats off, Mockito-team. This developer appreciates the extra few minutes you took to put together that message. It helped me immensely.

Wednesday, February 18, 2009

Tab navigating the Mac UI

It was driving me nuts when I got my MacBook that I could not use the tab button to navigate across a form. Let alone forms, on a browser page, I could only tab between the address bar and the search field. To go anywhere else, I had to reach for the mouse. Aaargh!!

Surely the operating system that was God's gift to humanity could do better than that! It took a fair amount of Googling for me to find the obscure setting that controls it.

Here's what you need to do in order to be able to tab away across the entire screen.

Bring up the System Preferences window and select Keyboard & Mouse from the Hardware Category.



From the "Keyboard & Mouse" panel, select the "Keyboard Shortcuts" tab. The magical setting is at the bottom of that tab. Allow "Full keyboard access" by selecting the "All controls" radio button.



As this panel shows, you can impress your colleagues by toggling this setting using CTRL+Fn+F7.

The question remains, who in their right mind thought that the default setting was to be "Text boxes and lists only"!!

Friday, February 13, 2009

JUnit 3 & JUnit 4: Oil & water

Version 4 of the popular JUnit test framework has been available for use for quite some time (In fact, it is up to version 4.5). However, many projects have a wealth of JUnit 3-style tests and developers may choose to continue using it. If, on the other hand, you decide to dip your toes in JUnit 4 waters, make it a complete immersion. Don't try to mix and match.

As you may be aware, couple of the touted "benefits" of JUnit 4 are the obviation of extending the TestCase class and the identification of test and lifecycle methods (setUp and tearDown) using Java 5 annotations. For example, the following is a valid JUnit 4-style test case (minus the necessary imports):

public class BusinessLogicTests {
  @Before
  public void do_this_before_every_test() {
    // set up logic goes here
  }

  @After
  public void clean_up_after_a_test() {
    // teardown logic goes here
  }

  @Test
  public void addition() {
    assertEquals("Invalid addition", 2, 1+1);
  }
}

Observe how

  • The class does not extend TestCase

  • The "setup" and "tearDown" methods are identified by annotations

  • The test method does not require a "test" prefix and is also annotated


I'll let you be the judge of whether this is an improvement on JUnit 3. What I want to alert you to are the perils of subconciously mixing JUnit-3 and JUnit-4 style programming. Consider the following test case:

public class BusinessLogicTests extends TestCase {
  @Before
  public void do_this_before_every_test() {
    // set up logic goes here
  }

  @After
  public void clean_up_after_a_test() {
    // teardown logic goes here
  }

  @Test
  public void testAddition() {
    assertEquals("Invalid addition", 2, 1+1);
  }

  @Test
  public void subtraction() {
    assertEquals("Invalid subtraction", 1, 1-1);
  }
}

This will result in a green-bar even though there is an error in the test of subtraction. Can you guess why?

It was that pesky little extends TestCase that I added from force of habit. The flips the switch to JUnit-3, which knows nothing about annotations, ignores my setup and teardown methods and looks for methods prefixed by test. It completely ignores the method named subtraction!

And of course, conversely, the following is just a plain old Java class that won't be acknowledged by either JUnit-3 or JUnit-4.

public class BusinessLogicTests {
  public void testAddition() {
    assertEquals("Invalid addition", 2, 1+1);
  }
}

Final word of advice, if you are using Struts Test Case, you have no choice but to write JUnit-3 style tests since the parent class of the framework (MockStrutsTestCase) extends Junit-3's TestCase.

Tweety thoughts

    follow me on Twitter