biniam
biniam

Reputation: 8199

Grails Spock Mock Injected Service in Unit Test

How do I inject another service in a Grails UnitTest (Specification) using Spock?

class ServiceOne {

   ServiceTwo serviceTwo

    ModelOne getMethodOne(String name) {
       // do somethings here
       return serviceTwo.getMethodTwo(name)
    }
}

class ServiceTwo {

   ServiceTwo serviceTwo

    ModelOne getMethodTwo(String name) {
       // do somethings here
       return ModelOne.get(name)
    }
}

// Tests
import grails.test.mixin.Mock
import grails.test.mixin.TestFor
import spock.lang.Specification
/**
 * Tests for ServiceOne
 */
@TestFor(ServiceOne)
@Mock(ModelOne)
class ServiceOneSpec extends Specification {
/** Inject serviceTwo in here
    Otherwise the following exception is thrown
    java.lang.NullPointerException: Cannot invoke method getMethodTwo() on null object
*/

void "test method one"() {

    when:
    ModelOne modelOne = service.getMethodOne(name)

    then:
    modelOne != null
   }
}

Upvotes: 4

Views: 3811

Answers (2)

biniam
biniam

Reputation: 8199

This is how I solved my question - by creating an object of the Service (It is not singleton but it is fine since it is just for unit testing)

// Test Spec
import grails.test.mixin.Mock
import grails.test.mixin.TestFor
import spock.lang.Specification
/**
 * Tests for ServiceOne
 */
@TestFor(ServiceOne)
@Mock(ModelOne)
class ServiceOneSpec extends Specification {

    @Shared ModelOne modelOne
    def setup() {
        // the magic
        service.serviceTwo = new ServiceTwo()
        modelOne = service.serviceTwo.getMethodTwo("Name")
    }

    void "test method one"() {

        when:
        ModelOne modelOne = service.getMethodOne(name)

        then:
        modelOne != null
   }
}

Upvotes: 0

railsdog
railsdog

Reputation: 1501

Off the top of my head, this should get you started.

@TestFor(ServiceOne)
@Mock(ModelOne)
class ServiceOneSpec extends Specification {

   void "test method one"() {
      given:
         def mockServiceTwo = mockFor(ServiceTwo)
         // expect that getMethodTwo is called once
         mockServiceTwo.demand.getMethodTwo(1) { String name ->
            // for any arbitrary name value, return a new ModelOne
            return new ModelOne()
         }
         service.serviceTwo = mockServiceTwo.createMock()
      when:
         ModelOne modelOne = service.getMethodOne(name)

      then:
         modelOne != null
   }
}

Upvotes: -1

Related Questions