Testing Grails custom graphs with support for services and plug-ins

I have a custom taglib that needs to make calls to a service method, which in turn uses the Wslite plugin to send and receive SOAP messages, Taglib looks something like this.

class myTagLib { def myService def thisTag = { def parametersFromService = myService.method("argument") out << render(template:'/myFolder/myView', model:parametersFromService) } } 

I am trying to build a test for this taglib. My test looks something like this:

 void testThisTag() { def appliedTagLib = applyTemplate('<thisTag attr="value" />') def parametersFromService = myService.method("argument") def renderedTemplate = render(template:'/myFolder/myView', model:parametersFromService) assertEquals appliedTagLib, renderedTemplate } 

I started writing this as Unit test. I tried the simple annotation MockFor(MyService) , and made fun of them more carefully, but the myService object myService always null when taglib tried to call it.

Given this, I decided that it was best to do this as an integration test; which will provide me access to the plugin and service, no problem.

However, the applyTemplate method only works if your test class extends GroovyPagesTestCase. If you do this, the rendering method does not work, at least not in the integration test. I know that applyTemplate and render work together with each other in the unit test for taglib since I tested the other taglib in this way.

It seems I'm between a rock and a solid place. To access the service, plugin, and SOAP service that they call, I need an integration test. To use the applyTemplate () method, I need to extend GroovyPagesTestCase, but this violates the rendering method. I tried adding import grails.test.GroovyPagesTestCase to my test class and then calling the applyTemplate method, but this leads to the absence of a method exception.

Thoughts?

Grails version 2.0.1, but I could upgrade to 2.2.1 if that helps (our site is in the process of transition).

--- Adding ----- elias suggested that I can inject an instance of grails.gsp.PageRenderer to get a working rendering method. I tried to build one:

 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())) } 

But get this error:

 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) 
+4
source share
3 answers

So, I ended up doing this to extend GroovyPagesTestCase to get applyTemplate and then introduce groovyPageRenderer as suggested by elias. Migrate Note: You must call your nested PageRenderer groovyPageRenderer for spring to complete the wiring you need. So my test class looked like this:

 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 } } 
+1
source

I struggled with something similar a few days ago, this is how I solved it:

  • Keep the test as in the integration test (no need to extend anything)
  • Take an instance of taglib bean using grailsApplication.mainContext.getBean
  • Test it with a method call

And this!:)

 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() } } 
+6
source

A cleaner solution will use GroovyPageUnitTestMixin as it already contains a rendering method.

 @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 } } 

A good review of some simple taglib testing can be found here: http://mrhaki.blogspot.com/2013/05/grails-goodness-testing-views-and.html

0
source

Source: https://habr.com/ru/post/1486282/


All Articles