unit-testinggrailsmockingspock

Mocking a Superclass in Spock


How can you unit test a class that has a superclass in Spock that invokes method calls form its superclass? Or how do you mock a superclass in Spock?

Ex:

class Bar {

  def method1(parm1){
      //Method actions
  }
}


class Foo extends Bar {

   def method2(param1, param2) {          
       //Method actions
       super.method1(param1)
   }
}

How can I mock behavior of class Bar?


Solution

  • You might use your class Foo as a Spy. The spy will create an instance of your class Foo but gives you the possibility of mocking any public methods declared in your spies class hierarchy.

    def fooInstance = Spy(Foo)
    fooInstance.method1(_) >> 'return value'
    

    Update / Clarification

    Some claim that the answer is not correct. Yes, Spy seems to have limitations. Alternatively you can achieve the same thing by using Groovy meta class registry.

    Given the example below

    class Bar {
        def method1(String param1) {
            println('method1')
            return true
        }
    }
    
    class Foo extends Bar {
        def method2(String param1, String param2) {
            println('method2')
            return method1(param1)
        }
    }
    
    
    def foo = new Foo()
    
    // Override method1 for this specific instance
    foo.metaClass.method1 = { String param1 ->
        println('overridden method1 for foo instance')
        return false // or whatever you want to return
    }
    
    // Test it
    foo.method1("test")        // Prints: overridden method1 for foo instance
    foo.method2("hello", "world") // Prints: method2, then: overridden method1 for foo instance
    

    This will result in

    overridden method1 for foo instance
    method2
    overridden method1 for foo instance
    

    and I believe this is exactly what was asked for.