söndag 8 november 2009

first steps in TDD with Scala

After using scala for some time in some small projects, i finally felt i was confident enough to start using TDD in scala aswell. I had earlier noted that Specs recently got Mockito support. which made me realy happy since i realy like Mockito from my java testing.
So i added Specs and Mocito to my project.

After creating some simple functionality in my service, i realised that now i need to call my DAO. In java, i would have passed the interface for my Dao into the service, and then use Mockito to expect a call to the method assign a return value and verify it was called.
Now this is Scala, there are traits instead of interfaces. I realised i had no clue what to do. I could try to do it the same way as in java. But it feelt so wrong. I dont want to go on like i was using java, since im not.
After asking some on twitter, and thinking alot. i decided with something that atleast feel abit more scala then java. Im not entierly satisfied, but its a start.

i created a simple trait, not doing anything that an Interface in java cant. There i put the methods that would access the dao. i then implemented the methods in my service.
In my test, i created a new trait, extending the dao trait. and implementing the methods returning something i could use to check for in my test. i then created an instance of my service and added my mockedTrait to it. very neat, i didnt even need any mocking tool. or rather, i didnt even see a way to use my old fellow mockito.

so in the end i ended up with something like this.

trait MyDao {
def getObject(id : Int) : MyObject
def createObject() : MyObject
}


class SUT extends MyDao {
  def getOrCreate(id : Int) : MyObject = {
    id match {
      case i:Int if i>0 => getObject(id)
      case _ => createObject()
    }
  def getObject(id : Int) : MyObject = {
    //some nastu dao accessing code
  }
  def createObject() : MyObject = {
    //some nastu dao accessing code
  }
}

Then in my Spec test
val createdObject = new MyObject(1)
val existingObject = new MyObject(2)

trait MockeMyDao extends MyDao{
  def getObject(id : Int) : MyObject = existingObject
  def createObject() : MyObject = createdObject
}

Then my test:
val mySUT = new SUT with MockedMyDao

"my SUT should return the object if it already exists " in {
   mySUT.getOrCreate(12) must be equalTo(existingObject)
}
"my SUT should create and return the object if it doesnt exist " in {
   mySUT.getOrCreate(-1) must be equalTo(createdObject)
}


As previously stated, im still not happy. It feels like im still partialy (or alot) in java land. Its not that there is anything wrong with that. Its pretty easy to follow and understand what everything does. But i can do bether, i realy can...

Inga kommentarer:

Skicka en kommentar