Search code examples
groovyspock

Behaviour test using parametrised Spock framework


I have a set of behavior tests which should result in the same outcome

def 'behaviour tests for route A'() {
 when:
   doA();

 then:
  data == 'Hi'
}

def 'behaviour tests for route B'() {
 when:
   doB();

 then:
  data == 'Hi'
}

void doA(){
 ...
}

void doB(){
 ...
}

the code looks ugly I would have preferred to use parametrized testing. something alongside this:

@Unroll
def 'behaviour tests for route #name'() {
     when:
       route
    
     then:
      data == 'Hi'

     where:
      name | route
      'A'  | doA()
      'B'  | doB()
}

Is there a way to do it?


Solution

  • You can use closures to extract the code that you want executed in the when block.

    class ClosureSpec extends Specification {
    
      @Unroll
      def 'behaviour tests for route #name'() {
        when:
        def data = route()
    
        then:
        data == 'Hi'
    
        where:
        name | route
        'A'  | { doA() }
        'B'  | { doB() }
      }
    
      def doA() {
        return 'Hi'
      }
    
      def doB() {
        return 'Hi'
      }
    }
    

    or you could use groovys dynamic nature to pass in the method name

    class DynamicSpec extends Specification {
    
      @Unroll
      def 'behaviour tests for route #name'() {
        when:
        def data = this."do$name"()
    
        then:
        data == 'Hi'
    
        where:
        name | route
        'A'  | _
        'B'  | _
      }
    
      def doA() {
        return 'Hi'
      }
    
      def doB() {
        return 'Hi'
      }
    }
    

    Depending on the use-case I'd go with the closure, but the dynamic method name has its uses, especially if you want to pass in parameters.