Archive

Posts Tagged ‘TDD’

Mocking and stubbing in Groovy with ‘with’

October 5, 2009 1 comment

I often use metaClass in Groovy to create mocks or stubs in my unit tests. Recently I’ve discovered that the with method makes this a bit simpler.

This:

Foo.metaClass.with {
  doSomething = {
    return true
  }
  anotherThing = {foo ->
    assertEquals 42, foo
  }
}

is slightly shorter than this:

Foo.metaClass.doSomething = {
  return true
}
Foo.metaClass.anotherThing = {foo ->
  assertEquals 42, foo
}

and less code means less bugs.

[Update: For more explanation of why the with method is so great, read this post.]
[Update: And for another way to write your mocks and stubs, see my previous post on mocking with Groovy.]

Integrating Unit Tests

August 19, 2009 Leave a comment

There’s been a lot of talk about TDD, Responsibility Driven Design, and what constitutes a unit test versus an integration test this week at work.  It got me thinking about the definitions.  I used to think it was very clear cut. Unit tests isolate a single class, integration test don’t.

Is the line so simple though?  What about a unit test that tests a method that uses other methods within the same class to get its work done.  Is testing the results of that method a unit test?

For example:

// Say I wanted to test the method.
String makeDeposit( String xmlData ) {
def transaction = parseRequestXml( request )
def receipt = bankBusinessObject.deposit( transaction )
return makeResponseXml( receipt )
}

To be a unit test, I should at least mock the bankBusinessObject, and should probably ask the Mock to fail my test if the deposit method isn’t called.

But, it seems that to be a true unit test for makeDeposit, I should also mock parseRequestXml and makeResponseXml. And, for the makeDeposit unit test, rather than test that you get the expected xml repsponse data given the controlled input data, just ensure that makeDeposit calls parseRequestXml to parse it, bankBuisinessObject.deposit to act on it, and makeResponseXml to marshal the results.

I did some brain storming and came up with a new classification scheme for organizing my tests.

Unit

  • Macro Unit Tests – Tests isolated to a single class.  This is where you’d see testing of methods which call other methods to get some of their work done.
  • Micro Unit Tests – Tests isolated to a single method.  Completely test the method in isolation, mocking as necessary.   If you work in a language like Groovy and want to unit test a method that calls or depends on other methods in the same class, mock the dependent methods individually and have the mocks fail the test if they’re not called as expected, in the order expected.  I’m not sure if that is possible in Java.  (Maybe with some sort of test harness with AOP involved to intercept the method calls during the test??)

Integration

  • Standard Integration Tests – Integration tests that span other methods, classes, depend on other services, databases, etc.
  • Requirements Tests – Tests for those when you want to test a specific requirement or bug fix.  Very helpful when something changes later that breaks the bug you fixed a few releases back.  Or when the customer opens a ticket asking for functionality that contradicts a previous request.

Thoughts?

Who needs a mock framework?

July 26, 2009 12 comments

In Groovy, you can create mocks & stubs using native language features, so you can forget about learning a mock framework.

class Author {
  def getName() {
    return 'Josh Brown'
  }
  def isFamous() {
    return false
  }
}

Let’s stub the isFamous method:

def author = [isFamous: {true}] as Author
assert 'Josh Brown' == author.getName()
assert author.isFamous()

(If you haven’t already, stick the above code in your groovyConsole, run it, and play around with it.)

When mocking and stubbing are so easy to do with the language itself, using a mock framework is overkill.

[Update: Bob Martin recently wrote an excellent post about Manual Mocking.]

Tags: , ,

Story time with easyb

January 27, 2009 2 comments

Everyone loves a good story.
 

Star Wars Trilogy

 

With easyb, you can write stories in your code!

scenario "the Death Star destroys Alderaan", {
    given "the Death Star", {}
    and "Alderaan", {}
    and "Alderaan is targeted by the Death Star", {}
    when "the Death Star fires", {}
    then "Alderaan is destroyed", {}
 }

You probably could’ve written that with the stakeholders yelling over shoulder. No – the Death Star should destroy Yavin IV, not Alderaan!!! If you’re writing readable code in front of them, you might be able to get them to make a decision while you’re at your keyboard.

Now you have executable documentation, and the stakeholders can leave the party. And once they’re gone, you can move on to writing some Groovy code to fill in those empty squiggly braces:

scenario "the Death Star destroys Alderaan", {
    given "the Death Star", {
        deathStar = new DeathStar()
    }
    and "Alderaan", {
        alderaan = new Planet(name:"Alderaan")
        Galaxy.planets << alderaan
    }
    and "Alderaan is targeted by the Death Star", {
        deathStar.target = alderaan
    }
    when "the Death Star fires", {
        deathStar.fire()
    }
    then "Alderaan is destroyed", {
        Galaxy.planets.shouldNotHave alderaan
    }
}

Now run it and watch it fail. Ah, the joy of xDD…

From here, you can write the DeathStar, Planet, and Galaxy classes you need to make it pass. Run it again! Refactor! Repeat!

Now you have documentation that’s readable, executable, and verifies that your code does what it’s supposed to do! Wasn’t that easy?

Tags: , , ,
Follow

Get every new post delivered to your Inbox.