Wednesday, April 28, 2010

PowerMock - Mocking Statics - Supplemental Documentation

I have recently suffered through a bit of pain working with PowerMock.  It seemed extremely promising, as it sits on top of EasyMock, which we use for mock objects in our unit tests (it also works with Mockito, apparently), and promises to give you the tools to mock those pesky static calls that kill testability.  I had a few issues getting started, and they centered around jUnit 3.

PowerMock with jUnit 3

All the examples and documentation seem to be based on jUnit 4. This page has great examples on how to run your static mocking tests when running on jUnit 4, but how to do it on jUnit 3??  An extremely simple example of how to do this in jUnit 4 is here:


@RunWith(PowerMockRunner.class)
public class AwesomeTest {

  @PrepareForTest(StaticClass.class)
  public void testDoExecute() throws Exception {
    ...
    PowerMock.mockStatic(StaticClass.class);

    expect( StaticClass.doStuff( param ) ).andReturn( "yo!" );
    replay( StaticClass.class );

    //test some stuff!
  }
}


To accomplish the same thing in jUnit 3, without the annotation support, you can do this:



public class MyPowerMockSuite extends PowerMockSuite {

  public static TestSuite suite() throws Exception {
  
    return new PowerMockSuite(AwesomeTest.class);
  }
 
  public static void main(String[] args) throws Exception {
  
    junit.textui.TestRunner.run( suite() );
  }  
}

public class AwesomeTest {

  @PrepareForTest(StaticClass.class)
  public void testDoExecute() throws Exception {
    ...
    PowerMock.mockStatic(StaticClass.class);

    expect( StaticClass.doStuff( param ) ).andReturn( "yo!" );
    replay( StaticClass.class );

    //test some stuff!
  }
}



PowerMock and Multiple Classes

To mock methods from multiple classes, you will need to amend the '@PrepareForTest' annotation, just passing a string array like so:



public class MyPowerMockSuite extends PowerMockSuite {

  public static TestSuite suite() throws Exception {
  
    return new PowerMockSuite(AwesomeTest.class);
  }
 
  public static void main(String[] args) throws Exception {
  
    junit.textui.TestRunner.run( suite() );
  }  
}

public class AwesomeTest {

  @PrepareForTest({StaticClass.class,StaticClassier.class})
  public void testDoExecute() throws Exception {
    ...
    PowerMock.mockStatic(StaticClass.class);

    expect( StaticClass.doStuff( param ) ).andReturn( "yo!" );
    replay( StaticClass.class );

    PowerMock.mockStatic(StaticClassier.class);

    expect( StaticClassier.doStuff( param ) ).andReturn( "yo!" );
    replay( StaticClassier.class );

    //test some stuff!
  }
}


Gotchas

PowerMock 1.3.7 only works with EasyMock 2.5.2, which we have had some issues with.  I had to move back to PowerMock 1.2.5 to use EasyMock 2.4.  I didn't find a lot of issues with using this version, though we had some odd calls that were required where it told me not to stub a return when the method returned something, or where I had to stub out calls that didn't seem like they should be required.  With a simple static method that didn't really call many other static methods, it seems to work like a charm.

Wednesday, April 14, 2010

How Five Guys Got Big...by being Awesome

About once a month when I was young (late 80s into the 90s), my dad and I went to this ratty little burger shop to get the most delicious burgers and out of this world fries at a place called 'Five Guys'.  The people were always friendly, and the order was always perfect.  It was no frills but they promised delicious burgers and fries, and it's what they delivered, without exception.

Fast forward to today, and Five Guys is EVERYWHERE.  It's growing in leaps and bounds - they even have them here in Colorado, with 400 to come in California!  Read the story in Inc. Magazine about how they got here.  You can really learn a lot from the way this business is run.

In an age when we understand that eating burgers and fries is not good for you, if you are going to do it, don't do it at McDonald's.  Go get something worth splurging on.