Search code examples
grailsgsptaglib

Testing Grails taglibs that call other taglibs


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

  • 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.