Grails controller unit tests with Joda Time

别来无恙 提交于 2019-12-08 01:59:29

问题


Some of the controller tests that generate-all creates are failing when I have a domain object with a Joda LocalDateTime field.

$ grails create-app bugdemo
$ cd bugdemo
$ grails create-domain-class Item

Edit grails-app/domain/bugdemo/Item.groovy

package bugdemo
import org.joda.time.LocalDateTime

class Item {
    String name
    // LocalDateTime opening
    static constraints = {
        name blank:false
    }
}

Add the following line to BuildConfig.groovy

compile ":joda-time:1.4"

Continue at the command line

$ grails compile
$ grails install-joda-time-templates
$ grails generate-all bugdemo.Item
$ grails test-app *ItemController

Several errors are reported. Fix these by editing the TODO areas of the ItemControllerTests

def populateValidParams(params) {
    assert params != null
    // TODO: Populate valid properties like...
    //params["name"] = 'someValidName'
    params["name"] = "Name"
}

and

   // test invalid parameters in update
    params.id = item.id
   //TODO: add invalid values to params object
    params.name = ""

Now all the controller tests pass.

Now uncomment the LocalDateTime field in Item.groovy. Those controller tests don't pass any more. I assume I need to add more params to fill in the opening object. But what parameters are passed? If I run the application, I can look at the form and see the following fields and values:

name: "Some Name"
opening: "struct" (hidden)
opening_day: "20"
opening_month: "7"
opening_year: "2013"
opening_hour: "22"
opening_minute: "20"

So I modify the code in closure populateValueParams as follows:

def populateValidParams(params) {
    assert params != null
    // TODO: Populate valid properties like...
    //params["name"] = 'someValidName'
    params["name"] = "Name"
    params["opening"] = "struct"
    params["opening_day"] = "20"
    params["opening_month"] = "07"
    params["opening_year"] = "2013"
    params["opening_hour"] = "22"
    params["opening_minute"] = "20"
}

The errors are still there when I run the tests. It seems that the Item object is not being saved correctly, presumably because the LocalDateTime field is not populated correctly in the test environment (even though it is in the dev environment).

$ grails test-app *ItemController

| Running 8 unit tests... 2 of 8                                                            
| Failure:  testShow(bugdemo.ItemControllerTests)                                           
|  Assertion failed:                                                                        

assert item.save() != null                                                                  
       |    |      |                                                                        
       |    null   false                                                                    
       bugdemo.Item : (unsaved)                                                             

        at bugdemo.ItemControllerTests.testShow(ItemControllerTests.groovy:69)              
| Running 8 unit tests... 3 of 8                                                            
| Failure:  testSave(bugdemo.ItemControllerTests)                                           
|  Assertion failed:                                                                        

assert response.redirectedUrl == '/item/show/1'                                             
       |        |             |                                                             
       |        null          false                                                         
       org.codehaus.groovy.grails.plugins.testing.GrailsMockHttpServletResponse@d67c36      

        at bugdemo.ItemControllerTests.testSave(ItemControllerTests.groovy:55)              
| Running 8 unit tests... 6 of 8                                                            
| Failure:  testEdit(bugdemo.ItemControllerTests)                                           
|  Assertion failed:                                                                        

assert item.save() != null                                                                  
       |    |      |                                                                        
       |    null   false                                                                    
       bugdemo.Item : (unsaved)                                                             

        at bugdemo.ItemControllerTests.testEdit(ItemControllerTests.groovy:87)              
| Running 8 unit tests... 7 of 8                                                            
| Failure:  testUpdate(bugdemo.ItemControllerTests)                                         
|  Assertion failed:                                                                        

assert item.save() != null                                                                  
       |    |      |                                                                        
       |    null   false                                                                    
       bugdemo.Item : (unsaved)                                                             

        at bugdemo.ItemControllerTests.testUpdate(ItemControllerTests.groovy:107)           
| Running 8 unit tests... 8 of 8                                                            
| Failure:  testDelete(bugdemo.ItemControllerTests)                                         
|  Assertion failed:                                                                        

assert item.save() != null                                                                  
       |    |      |                                                                        
       |    null   false                                                                    
       bugdemo.Item : (unsaved)                                                             
| Packaging Grails application.....                                                         

Is there some aspect of the Joda classes that needs to be mocked? When the controller says

    def itemInstance = new Item(params)

why does it work in dev, but not test? How does it work in dev?

I'm using Grails 2.2.3, Java 1.7.0_25, Windows 7.


回答1:


Unit tests don't setup custom property editors automatically (responsible to transform the submited info in the domain class instance).

Looking at the source, it seems that JodaTimePropertyEditorRegistrar is responsible for that. So in your test you can use defineBeans to add this Spring Bean:

import grails.plugin.jodatime.binding.JodaTimePropertyEditorRegistrar

class MyTest {
  @Before
  public void setup() {
    defineBeans {
      jodaTimePropertyEditorRegistrar(JodaTimePropertyEditorRegistrar)
    }
  }
}



回答2:


You can use an object to set the DateTime() or other joda-time values in the populateValidParams() method...

def populateValidParams(params) {
    assert params != null
    params["name"] = "Name"
    params["opening"] = new DateTime()
}


来源:https://stackoverflow.com/questions/17762321/grails-controller-unit-tests-with-joda-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!