0

Lets say I have a class Foo with two void methods bar and biz(Object object)

public class Foo {
  public void bar(){}
  public void biz(Object object){}
}

Both methods are complex methods with their own test cases but the problem is bar() calls biz(Object object) and I want to verify this in one of bar's test cases. So my test case is set up something like this in Spock.

class FooSpec {
  Foo foo = new Foo()
  
  def "test bar"() {
     given:
       boolean bizCalled = false
       foo.metaClass.biz = {Object object -> bizCalled = true}
     when:
       foo.bar()
     then:
       0 * _
     and:
       bizCalled
  }
}

I got this solution from this question the problem is that in this example bizCalled is always false causing the assertion to fail even though I've verified that biz(Object object) so bizCalled should be getting set to true.

Is there simply something wrong with the way I'm using metaClass or is there a more correct way in spock to verify that bar() calls biz(Object object) in Spock?

Working Title
  • 254
  • 7
  • 28

1 Answers1

3

You forgot to make FooSpec extend Specification in order to really make it a Spock test. If you do that, the test passes. Here is your slightly adjusted and renamed original test:

public class Foo {
  public void bar() { biz("dummy"); }
  public void biz(Object object) {}
}
import spock.lang.Specification

class InternalMethodCallTest extends Specification {
  Foo foo = new Foo()

  def "bar calls biz"() {
    given:
    boolean bizCalled = false
    foo.metaClass.biz = { Object object -> bizCalled = true }

    when:
    foo.bar()

    then:
    0 * _

    and:
    bizCalled
  }
}

But that is not just ugly, it is also "un-spockish". I suggest you simply use a Spy in order to verify internal method calls:

import spock.lang.Specification

class InternalMethodCallTest extends Specification {
  Foo foo = Spy()

  def "bar calls biz"() {
    when:
    foo.bar()

    then:
    1 * foo.biz(_)
  }
}
kriegaex
  • 63,017
  • 15
  • 111
  • 202