Unit test Groovy2.0 with Spock : setup( )
Asked Answered
A

1

13

I am writing unit test using Spock for groovy-2.0 , and using gradle to run. If I write following the test pass.

import spock.lang.Specification

class MyTest extends Specification {  

  def "test if myMethod returns true"() {       
    expect:
      Result == true;   
    where: 
      Result =  new DSLValidator().myMethod()

  }  
}  

myMethod() is a simple method in DSLValidator class, that simply returns true.

But if I write a setup() function and create the object in setup(), my test fails: Gradel says: FAILED: java.lang.NullPointerException: Cannot invoke method myMethod() on null object

Following is what it looks like with setup(),

import spock.lang.Specification

class MyTest extends Specification {  

  def obj

  def setup(){
   obj =  new DSLValidator()
  }

  def "test if myMethod returns true"() {       
    expect:
      Result == true;   
    where: 
      Result =  obj.myMethod()

  }  
}     

Can somebody help?

Here is the solution I got to the problem:

import spock.lang.Specification

class DSLValidatorTest extends Specification {

  def validator

  def setup() {
    validator = new DSLValidator()
  }


  def "test if DSL is valid"() { 

      expect:
        true == validator.isValid()
  }  
}
Awfully answered 31/1, 2012 at 18:18 Comment(0)
T
27

In Spock objects stored into instance fields are not shared between feature methods. Instead, every feature method gets its own object.

If you need to share an object between feature methods, declare a @Shared field.

class MyTest extends Specification {
    @Shared obj = new DSLValidator()

    def "test if myMethod returns true"() {       
        expect:
          Result == true  
        where: 
          Result =  obj.myMethod()
    }
}

class MyTest extends Specification {
    @Shared obj

    def setupSpec() {
        obj = new DSLValidator()
    }

    def "test if myMethod returns true"() {       
        expect:
          Result == true  
        where: 
          Result =  obj.myMethod()
    }
}

There are 2 fixture methods for setting up the environment:

def setup() {}         // run before every feature method
def setupSpec() {}     // run before the first feature method

I don't understand why the second example with setupSpec() works and fails with setup() because in documentation says otherwise:

Note: The setupSpec() and cleanupSpec() methods may not reference instance fields.

Tumultuous answered 31/1, 2012 at 20:56 Comment(3)
Weird... The Spock docs could really do with clarification on this... I wouldn't say that obj is being shared between feature methods, but is being set up prior to each fixture being called...Gumshoe
What is it that you don't understand? A @Shared field is shared between feature methods and should be set up with a field initializer or the setupSpec method. setup is not a good choice here because it gets called after the where block has been evaluated.Daimon
Thanks everyone for helping me here. I do not want to use the shared field as that will cause failing other test in future. Need to have individual instance of DSLValidator for each feature method. The problem is what Peter Niederwieser mention "setup is not a good choice here because it gets called after the where block has been evaluated." I ultimately figured out that "where" block is not good here if I want to use setup and do not want a shared instance among the future method. Please see, I edited my original question with my solution. Thank you all again.Awfully

© 2022 - 2024 — McMap. All rights reserved.