Say I've got two taglibs, Foo
which does something specific for a particular part of my application, and Util
which is shared across the whole thing. I want to do something like this:
class UtilTagLib {
def utilTag = { attrs ->
...
}
}
class FooTagLib {
def fooTag = {
...
out << g.utilTag(att1: "att1", att2: "att2")
...
}
}
However, when I do this, and try to run my unit test for fooTag()
, I get:
groovy.lang.MissingMethodException: No signature of method: org.codehaus.groovy.grails.web.pages.GroovyPage.utilTag() is applicable for argument types: (java.util.LinkedHashMap) values: [[att1:att1, att2:att2]]
I tried giving UtilTagLib
its own namespace
static namespace = "util"
and changing the call to
out << util.utilTag(...)
but this just gets me
groovy.lang.MissingPropertyException: No such property: util for class: org.example.FooTagLib
Possibly also of note: In the log, I see:
WARN - Bean named 'groovyPagesUriService' is missing.
Obviously, UtilTagLib
isn't getting created and injected correctly. How can I fix this?
Solution: add the call
mockTagLib UtilTagLib
to the setUp()
(or @Before
) method of the test case. This is a method on GroovyPageUnitTestMixin that, somewhat counterintuitively, instantiates the specified tag library -- the real one, not a mock -- and wires it into the Grails application context. It's used internally to set up the actual taglib under test (in this case FooTagLib
), but it also works to set up additional collaborator tag libs.
Note that this isn't perfect, since it makes it more of an integration test than a pure unit test -- ideally we would be using a mock UtilTagLib
and just testing the interaction.