假设我有两个taglib,Foo
为我的应用程序的特定部分执行特定的操作,Util
在整个事件中共享。我想做这样的事情:
class UtilTagLib {
def utilTag = { attrs ->
...
}
}
class FooTagLib {
def fooTag = {
...
out << g.utilTag(att1: "att1", att2: "att2")
...
}
}
然而,当我这样做,并尝试为fooTag()
运行我的单元测试时,我得到:
groovy.lang.MissingMethodException:没有方法签名:org.codehaus.groovy.grails.web.pages.GroovyPage.utilTag()适用于参数类型:(java.util.LinkedHashMap)值:[[att1: att1,att2:att2]]
我尝试给UtilTagLib
自己的命名空间
static namespace = "util"
并将通话更改为
out << util.utilTag(...)
但这只是让我
groovy.lang.MissingPropertyException:没有这样的属性:util for class:org.example.FooTagLib
可能还需要注意:在日志中,我看到:
警告 - 缺少名为'groovyPagesUriService'的Bean。
显然,UtilTagLib
没有被正确创建和注入。我该如何解决这个问题?
答案 0 :(得分:3)
解决方案:添加通话
mockTagLib UtilTagLib
到测试用例的setUp()
(或@Before
)方法。这是GroovyPageUnitTestMixin上的一个方法,有点违反直觉,实例化指定的标记库 - 真正的标记库,而不是模拟 - 并将其连接到Grails应用程序上下文中。它在内部用于设置测试中的实际taglib(在本例中为FooTagLib
),但它也可用于设置其他协作者标记库。
请注意,这并不完美,因为它使它更像是一个集成测试,而不是纯单元测试 - 理想情况下,我们将使用模拟UtilTagLib
并仅测试相互作用。
答案 1 :(得分:1)
一种方法是重构线:
out << g.utilTag(att1: "att1", att2: "att2")
进入自己的方法,比如&#34; renderUtilTag(...)&#34;然后在单元测试中模拟出来,例如:
FooTagLib.metaClass.renderUtilTag = { /* something */ }
这样你只在单元测试中测试FooTagLib的功能,而不依赖于UtilTagLib。