Check grails data binding

I wrote the following Grails controller

class CategoryController { def create = { def newCategory = new CategoryCommand() bindData(newCategory, params) [newCategory: newCategory] } } class CategoryCommand { String name String seoName } 

I wrote this unit test to check for data binding:

 class CategoryControllerTests extends ControllerUnitTestCase { void testCreate() { // A new ControllerCommand should be returned if invoked with no params assertNotNull controller.create() // If called with params, they should be bound mockParams.name = 'snooker' mockParams.seoName = 'snooker-loopy' def model = controller.create() CategoryCommand newCategory = model.newCategory assertEquals 'snooker', newCategory.name assertEquals 'snooker-loopy', newCategory.seoName } } 

But I get this exception when controller.create() is called:

No method signature: com.example.CategoryController.bindData () is applicable for argument types: (com.example.CategoryCommand, org.codehaus.groovy.grails.web.taglib.GroovyPageAttributes) values: [com.example.Categoryand @ 7860e7d2, [:]]

I tried using this instead of the integration test, but the result is the same.

+7
source share
4 answers

That's right ... I did a little work and found this blog page that says (about halfway down):


Note: ControllerUnitTestCase does not support some dynamic method. For instance: bindData (). Then better use integration testing, or you can add this method to the controller:

 this.controller.metaClass.bindData = { obj, params -> params.each { key, value -> obj."$key" = value } } 

Or, I looked into the Grails source code and scoffed at doing the same thing as what Grails does , I think you will need to do:

 import org.codehaus.groovy.grails.web.metaclass.BindDynamicMethod this.controller.metaClass.bindData = { obj, params -> new BindDynamicMethod().invoke( delegate, BindDynamicMethod.BIND_DATA_METHOD, [ obj, params ] as Object[] ) ; } 

(I think - did not test it)

+6
source

As mentioned earlier, simulates Grails using BindDynamicMethod. This works for me on Grails 1.3.5:

 import org.codehaus.groovy.grails.web.metaclass.BindDynamicMethod protected void setUp() { def mc = controller.class.metaClass def bind = new BindDynamicMethod() mc.bindData = { Object target, Object args -> bind.invoke(delegate, "bindData", [ target, args ] as Object[]) } mc.bindData = { Object target, Object args, List disallowed -> bind.invoke(delegate, "bindData", [ target, args, [ exclude: disallowed ]] as Object[]) } mc.bindData = { Object target, Object args, List disallowed, String filter -> bind.invoke(delegate, "bindData", [ target, args, [ exclude: disallowed ], filter ] as Object[]) } mc.bindData = { Object target, Object args, Map includeExclude -> bind.invoke(delegate, "bindData", [ target, args, includeExclude ] as Object[]) } mc.bindData = { Object target, Object args, Map includeExclude, String filter -> bind.invoke(delegate, "bindData", [ target, args, includeExclude, filter ] as Object[]) } mc.bindData = { Object target, Object args, String filter -> bind.invoke(delegate, "bindData", [ target, args, filter ] as Object[]) } } 

This is copied from org/codehaus/groovy/grails/plugins/web/ControllersGrailsPlugin.groovy and therefore supports all forms of bindData .

We hope that the situation will improve with the upcoming Grails 1.4 and testing mixins .

+3
source

Here are two possible solutions:

  • Try running it again as an integration test .;) I moved your test class to the test / integration folder and it passed for me. I also run Grails 1.3.6.

  • Change your controller to not use bindData. This controller action is equivalent to what you have now, and it will pass your unit test:

     def create = { def newCategory = new CategoryCommand(params) [newCategory: newCategory] } 

    one drawback is that only bindData can bind data for related objects if you have a parameter name, such as "myAssociation.myProperty".

0
source

ControllerUnitTestCase does not support the bindData() method.

JIRA has a problem open:
I would like to see the laughing bindData () method on ControllerUnitTestCase

I am writing minimal code to pass unit test:

 controller.metaClass.bindData = { obj, params -> obj.properties = params } 
0
source

All Articles