Friday, May 16, 2008

DGG Confusion #1 (among many to come, I'm sure)

I'm working my way through The Definitive Guide to Grails. Chapter 6 covers testing, and I'm a bit stuck on the GroovyMock example in listing 6-9. I'm using Grails 1.0.2, and as entered*, the test fails with "No call to 'getParams' expected at this point. Still 1 call(s) to 'redirect' expected." I tried demanding a call to getParams, but that leads down a path of yet more confusing errors.

So, I'll keep beating my head against it for a while, and hopefully post back with some results.

*
void testUpdateNotFound() {
def bc
def mock = new MockFor(BookmarkController)
mock.demand.redirect { Map params ->
assert params.action == bc.edit
}
mock.use {
bc = new BookmarkController()
bc.params.id = 5
bc.update.call()
}
}

[UPDATE] Nothing that a little Googling won't help, and I'm happy to know I'm not just insane (well, at least not with this particular problem). I'm using version 1.5.1, and according to a bug report, Groovy's MockFor is a bit squiffy in versions 1.5.1 and 1.5.4. Unfortunately, the bug's still open, so I'll have to pass over that part of the book for now. I can do that in good conscience. :o)

[UPDATE #2] This works with Groovy 1.5.6 (with "method pointers"):
import groovy.mock.interceptor.*

class BookmarkController {
def update = { redirect("value from original") }
def redirect = { println "Original class: $it" }
}

class BookmarkTests extends GroovyTestCase {
void testUpdate() {
def bc
def mock = new MockFor(BookmarkController)
mock.demand.redirect { println "Mock class: $it" }
mock.use {
bc = new BookmarkController()
bc.&update.call()
}
}
}

new BookmarkController().&update.call()
new BookmarkTests().testUpdate()

...but I'm not sure that does much for DGG Listing 6-9. Hmph.