0

I am using Spock for unit tests. I want to test Java methods and classes dynamically as in below example. Audit is a Java class. In addition, if possible, I would also like to make Audit class a parameter

given:
     Audit audit = GroovyMock()
     expression
     BatchAudit bean = new BatchAudit()

when:
    bean.insertAudit(audit)
then:
    thrown(exc)
where:
    expression | exc
    audit.getFileName() >> {throw new SQLException(new Throwable())} | DataAccessException
Leonard Brünings
  • 12,408
  • 1
  • 46
  • 66
Harish
  • 19
  • 2

1 Answers1

1

It is possible with a few modifications:

  1. you need to make expression a closure (due to some quirks in the AST, closures can't be the first element in a data table, so it must switch places with expectedException)
  2. you need to restore the context for the closure with expression.rehydrate(null, this, this)
  3. you need to pass the mock instance to the closure as parameter
import spock.lang.*

class Audit {
  String getFileName() {
    "foo"
  }
}

class BatchAudit {
  void insertAudit(Audit a) {
    println a.getFileName()
  }
}

class ASpec extends Specification {
  def "test"() {
    given:
    Audit audit = Mock()
    // we need to rehydrate the closure, so that `this` and are correct
    expression.rehydrate(null, this, this).call(audit)
    BatchAudit bean = new BatchAudit()

    when:
    bean.insertAudit(audit)
      
    then:
    Exception e = thrown()
    expectedException.isInstance(e)
      
    where:
    expectedException     | expression
    IllegalStateException | { it.getFileName() >> { throw new IllegalStateException() } }
  }
}

Try it out in the Groovy Webconsole.

Leonard Brünings
  • 12,408
  • 1
  • 46
  • 66