使用服务和插件依赖项测试自定义 Grails Taglib
Posted
技术标签:
【中文标题】使用服务和插件依赖项测试自定义 Grails Taglib【英文标题】:Testing Custom Grails Taglib with Service and Plugin Dependencies 【发布时间】:2013-06-11 09:54:06 【问题描述】:我有一个需要调用服务方法的自定义标记库,该方法又使用Wslite plugin 发送和接收 SOAP 消息。 taglib 看起来像这样。
class myTagLib
def myService
def thisTag =
def parametersFromService = myService.method("argument")
out << render(template:'/myFolder/myView',
model:parametersFromService)
我正在尝试为这个 taglib 构建一个测试。我的测试是这样的:
void testThisTag()
def appliedTagLib = applyTemplate('<thisTag attr="value" />')
def parametersFromService = myService.method("argument")
def renderedTemplate = render(template:'/myFolder/myView',
model:parametersFromService)
assertEquals appliedTagLib, renderedTemplate
我首先将其编写为单元测试。我尝试了简单的MockFor(MyService)
注释,以及mocking them in a more elaborate fashion,但是当taglib 尝试调用它时myService
对象始终为空。
鉴于此,我决定最好将其作为集成测试进行;这将使我可以访问插件和服务,没问题。
但是,applyTemplate 方法仅在您的测试类扩展 GroovyPagesTestCase 时才有效。但是,如果您这样做 that,则 render 方法不起作用,至少在集成测试中不起作用。我知道 applyTemplate 和 render do 在 taglib 的单元测试中相互配合,因为我已经以这种方式测试了其他 taglib。
我似乎在一块石头和一个坚硬的地方之间。为了访问他们调用的服务、插件和 SOAP 服务,我需要一个集成测试。要使用 applyTemplate() 方法,我需要扩展 GroovyPagesTestCase,但这会破坏渲染方法。我尝试将import grails.test.GroovyPagesTestCase
添加到我的测试类中,然后从中调用applyTemplate 方法,但这会导致缺少方法异常。
想法?
Grails 版本是 2.0.1,但如果有帮助,我可以升级到 2.2.1(我们的网站正在转换中)。
---附录----- elias 建议我可以注入一个 grails.gsp.PageRenderer 实例来获得一个有效的渲染方法。我试过构建一个:
import org.codehaus.groovy.grails.web.pages.GroovyPagesTemplateEngine
import grails.gsp.PageRenderer
...
def pageRenderer
...
void setUp()
context = grailsApplication.mainContext
taglib = context.getBean(myTagLib.class.name)
pageRenderer = new PageRenderer(new GroovyPagesTemplateEngine(context.getServletContext()))
但收到此错误:
java.lang.NullPointerException: Cannot invoke method findTemplateByPath() on null object
at grails.gsp.PageRenderer.renderViewToWriter(PageRenderer.groovy:120)
at grails.gsp.PageRenderer.render(PageRenderer.groovy:77)
at MyTagLibIntegrationTests.testThisTag(MyTagLibIntegrationTests.groovy:37)
【问题讨论】:
您不需要在setUp中初始化它,只需为实例使用正确的bean名称def groovyPageRenderer
就可以了。
【参考方案1】:
几天前我也在为类似的事情苦苦挣扎,我是这样解决的:
-
保持测试与集成测试相同(不需要扩展任何东西)
使用
grailsApplication.mainContext.getBean
获取taglib bean 的实例
使用方法调用对其进行测试
就是这样! :)
class MyTagLibTests
def grailsApplication
def taglib
@Before
void setUp()
// grab the taglib instance from Spring context
taglib = grailsApplication.mainContext.getBean(MyTagLib.class.name)
@Test
void myTestAboutThisTag()
def thisTagArgs = [:] // set up the arguments here
assert 'shouldResultThis' == taglib.thisTag(thisTagArgs).toString()
【讨论】:
这很有帮助,但是手动定义一个要比较的字符串让我像老猛犸一样伤心。我将看看是否可以找到某种方法使渲染方法可用,以便我可以与之进行比较。 对!我认为您可以在测试中注入groovyPageRenderer
的实例,并尝试使用它的渲染方法。
...但如果我能做到,为什么不扩展 GroovyPagesTestCase 并将 applyTemplate() 的输出与 render() 的输出进行比较?请参阅我对尝试注入 pageRenderer 的编辑。这可能只是我未能正确执行基本的依赖注入。
好吧,我认为你可以这样做,但它仍然只适用于只呈现模板的 taglib。我提供了我的方法作为标签库集成测试的更通用解决方案。
而且它非常有帮助,尤其是 groovyPageRenderer 评论,它让我走上了正轨。由于这个特定问题的目标是将 taglib 的输出与呈现的模板进行比较,因此我不能完全接受它作为答案,但我会尝试在应得的地方给予信任。 :)【参考方案2】:
所以,我最终所做的是扩展 GroovyPagesTestCase 以获得 applyTemplate,然后按照 elias 的建议注入 groovyPageRenderer。 Persnickity 注意:您必须调用注入的 PageRenderer groovyPageRenderer,以便 spring 为您完成所有适当的接线。所以我的测试类最终看起来像:
class myTaglibIntegrationTests extends GroovyPagesTestCase
PageRenderer groovyPageRenderer
def imageService
@Test
void testThisTag()
def appliedTagLib = applyTemplate('<thisTag attr="value" />')
def parametersFromService = myService.method("argument")
def renderedTemplate = groovyPageRenderer.render(template:'/myFolder/myView',
model:parametersFromService)
assertEquals appliedTagLib, renderedTemplate
【讨论】:
在此处查看 elias 的答案,了解另一个有用的想法,即为 taglib 进行测试,在其他情况下可能会更好地工作:***.com/a/17113855/1524502【参考方案3】:更简洁的解决方案是使用 GroovyPageUnitTestMixin,因为它已经包含一个渲染方法。
@grails.test.mixin.TestMixin(grails.test.mixin.GroovyPageUnitTestMixin)
class myTaglibIntegrationTests
def myService
@Test
void testThisTag()
def appliedTagLib = applyTemplate('<thisTag attr="value" />')
def parametersFromService = myService.method("argument")
def renderedTemplate = render(template:'/myFolder/myView',
model:parametersFromService)
assertEquals appliedTagLib, renderedTemplate
关于一些简单的 taglib 测试的好文章可以在这里找到:http://mrhaki.blogspot.com/2013/05/grails-goodness-testing-views-and.html
【讨论】:
以上是关于使用服务和插件依赖项测试自定义 Grails Taglib的主要内容,如果未能解决你的问题,请参考以下文章
Grails 中的 Spring Oauth2 提供程序 - 依赖项
Grails 使用 Spring Security Core Plugin 测试用户角色自定义验证约束
使用 grails 2.2.0 和资源插件找不到自定义 jquery css 图像
如何使用 grails 1.3.2 和插件 spring-security-core 1 实现自定义 FilterSecurityInterceptor?