Grails unit test mocking method in dependent service

168 views Asked by At

I have a service which uses another service, something like:

class ServiceA implements IFaceClass {
  ServiceB bServ
  @Override
  void functionA(Map map) {
    try {
      bServ.functionB() // this throws an exception on error
    } catch (Exception e) {
      log.warn("Exception occured: " + e.message)
    }
  }
}

Now I am trying to write a unit test that checks that the Exception is raised from bServ.functionB() and handled by functionA() by mocking that function with the following Spec.

class ServiceASpec extends Specification {
  ServiceB bServ
  def setup() {
    bServ = Mock(ServiceB)
    service.bServ = bServ
  }

  def "test exception raised by functionB is handled"() {
    given:
      bServ.functionB() >> {
        throw new Exception("some exception message")
      }
    when:
      service.functionA()
    then:
      1 * log.warn("Exception occured: some exception message")
  }
}

However I get an error with this test saying (0 invocations) of the log.warn statement.

Would appreciate any insights into why this test is not correct and how I can test that the exception is being handled correctly by functionA()

1

There are 1 answers

0
Opal On

Here You can find sample working test:

@Grab('org.spockframework:spock-core:0.7-groovy-2.0')
@Grab('cglib:cglib-nodep:3.1')
@Grab('org.slf4j:slf4j-api:1.7.12')

import spock.lang.*
import org.slf4j.Logger

class ServiceASpec extends Specification {

  def "test exception raised by functionB is handled"() {
    given:
      ServiceB serviceB = GroovyMock()
      serviceB.functionB() >> { throw new Exception("some exception message") }

    and:
       ServiceA serviceA = new ServiceA()
       serviceA.serviceB = serviceB
       serviceA.log = Mock(Logger)

    when:
      serviceA.functionA([:])

    then:
      1 * serviceA.log.warn("Exception occured: some exception message")
  }
}

class ServiceA {

  ServiceB serviceB
  Logger log

  void functionA(Map map) {
    try {
      serviceB.functionB() 
    } catch (Exception e) {
      log.warn("Exception occured: " + e.message)
    }
  }
}

class ServiceB {
  void functionB() {
  }
}