Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit test Groovy2.0 with Spock : setup( )

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()
  }  
}
like image 875
Masa Avatar asked Jan 31 '12 18:01

Masa


People also ask

How do I run the Groovy Spock test in IntelliJ?

Press Ctrl+Shift+T and select Create New Test. In the dialog that opens, specify your test settings and click OK. Open the test in the editor, add code and press Ctrl+Shift+F10 or right-click the test class and from the context menu select Run 'test name'.

Is Spock better than JUnit?

The main difference between Spock and JUnit is in breadth of capabilities. Both frameworks can be used for unit testing. However, Spock offers much more — including mocking and integration testing. JUnit requires a third party library for mocking.


1 Answers

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.

like image 120
Arturo Herrero Avatar answered Oct 02 '22 02:10

Arturo Herrero