I heard about “Spock” the testing framework earlier this year. When I watched a online screencast at the time, I was impressed! Few things that I liked about it was the “Simplicity” and “intuitiveness” it brings to the table.
I see it as “groovy” to groovy, as to groovy to java.(i.e. life made simpler)
To be honest, when I learnt about it earlier, I was little skeptic if this was going to be adopted well and gonna be there for a while. Recently I visited their portal and I was glad to see that it was “Highly Active”. So, here I am trying to give it a try.
Complete Source code could be found at my github, https://github.com/manijshrestha/SpockExample
I have a simple project set up using gradle.
In this example I am going to try to create a “InventoryManager” that manages inventory for a online store.
Here is my Manager code:
package com.manijshrestha.spockexample import com.manijshrestha.spockexample.exception.OutOfStockException import com.manijshrestha.spockexample.exception.NotEnoughInventoryException class InventoryManager{ private def items =[:] def getCountOfInventory(item){ items.get(item) } def gotTotalInventoryCount(){ def sum = 0 items.each{sum += it.value} return sum } def checkout(String item, int qty){ def availQty = items.get(item) if(availQty <= 0) throw new OutOfStockException() if(qty > availQty) throw new NotEnoughInventoryException() items.put(item, availQty - qty) } }
And here is a simple test class used to test this code:
package com.manijshrestha.spockexample import spock.lang.Specification import com.manijshrestha.spockexample.InventoryManager import com.manijshrestha.spockexample.exception.OutOfStockException import com.manijshrestha.spockexample.exception.NotEnoughInventoryException /** * Created by IntelliJ IDEA. * User: manijshrestha * Date: 10/12/11 * Time: 11:10 PM * To change this template use File | Settings | File Templates. */ class InventoryManagerTest extends Specification{ def inventoryManager = new InventoryManager() def "count of items in inventory"(){ when: inventoryManager.items = ["cd": 3] then: inventoryManager.getCountOfInventory("cd") == 3 } def "total count of all inventories"(){ when: inventoryManager.items = ["laptop": 10, "cellphone": 5, "tablet":5] then: inventoryManager.gotTotalInventoryCount() == 20 } def "throw exception when trying to checkout item out of stock"(){ when: inventoryManager.items = ["droidx": 0] inventoryManager.checkout("droidx", 1) // trying to buy droidx then: thrown(OutOfStockException) } def "throw exception when trying to checkout more qty than avail"(){ when: inventoryManager.items = ["led tv": 2] inventoryManager.checkout("led tv", 3) then: thrown(NotEnoughInventoryException) } def "reduces correct number of items"(){ when: inventoryManager.items=["dvd" : 10] inventoryManager.checkout("dvd", 7) then: inventoryManager.items.dvd == 3 } }
Few things I would like to point out here, the method names are Strings, which makes it a nice and readable test case rather than a camel cased or underscore delimited method names.
These tests I think are more readable and simple to understand. Well, I do have a very simple example here but with its power, I think writing complex test will still be simpler compared to regular jUnit tests.