Grails控制器单元测试Joda时间 [英] Grails controller unit tests with Joda Time
问题描述
当我有一个带有Joda LocalDateTime字段的域对象时,生成的所有控制器测试都会失败。
$ grails create-app bugdemo
$ cd bugdemo
$ grails create-domain-class Item
编辑grails-app / domain / bugdemo / Item.groovy
包bugdemo
导入org.joda.time.LocalDateTime
类项目{
字符串名称
/ / LocalDateTime打开
静态约束= {
空白名称:false
}
}
将以下行添加到BuildConfig.groovy中:
compile:joda-time:1.4
继续在命令行
$ grails编译
$ grails install-joda-time-templates
$ grails generate-all bugdemo.Item
$ grails test-app * ItemController
报告了一些错误。通过编辑ItemControllerTests的TODO区域来修复这些问题。
def populateValidParams(params){
assert params!= null
// TODO:填充有效的属性,如...
// params [name] ='someValidName'
params [name] =名称
}
和
params.id = item.id
// TODO:向params对象添加无效值
params.name =
现在所有的控制器测试都通过了。现在取消注释LocalDateTime Item.groovy中的字段。那些控制器测试不再通过。我假设我需要添加更多的参数来填充开始对象。但是传递了什么参数?如果我运行应用程序,我可以查看表单并查看以下字段和值:
name:某个名称
开头:struct(隐藏)
opening_day:20
opening_month:7
opening_year:2013
opening_hour:22
opening_minute:20
所以我修改了闭包populateValueParams中的代码,如下所示:
def populateValidParams(params){
assert params!= null
// TODO:填充有效的属性,例如.. 。
// params [name] ='someValidName'
params [name] =名称
params [opening] =struct
params [opening_day] =20
params [opening_month] =07
params [opening_year] =2013
params [opening_hour] =22
params [opening_minute] =20
}
当我运行测试时,错误仍然存在。看来Item对象没有正确保存,可能是因为LocalDateTime字段在测试环境中没有正确填充(即使它在开发环境中)。
$ grails test-app * ItemController
|运行8个单元测试... 2 of 8
|失败:testShow(bugdemo.ItemControllerTests)
|断言失败:
assert item.save()!= null
| | |
| null false
bugdemo.Item:(unsaved)
在bugdemo.ItemControllerTests.testShow(ItemControllerTests.groovy:69)
|运行8个单元测试... 3 of 8
|失败:testSave(bugdemo.ItemControllerTests)
|断言失败:
assert response.redirectedUrl =='/ item / show / 1'
| | |
| null false
org.codehaus.groovy.grails.plugins.testing.GrailsMockHttpServletResponse@d67c36
at bugdemo.ItemControllerTests.testSave(ItemControllerTests.groovy:55)
|运行8个单元测试... 6 of 8
|失败:testEdit(bugdemo.ItemControllerTests)
|断言失败:
assert item.save()!= null
| | |
| null false
bugdemo.Item:(unsaved)
ugdemo.ItemControllerTests.testEdit(ItemControllerTests.groovy:87)
|运行8个单元测试... 7 of 8
|失败:testUpdate(bugdemo.ItemControllerTests)
|断言失败:
assert item.save()!= null
| | |
| null false
bugdemo.Item:(unsaved)
在bugdemo.ItemControllerTests.testUpdate(ItemControllerTests.groovy:107)
|运行8个单元测试... 8 of 8
|失败:testDelete(bugdemo.ItemControllerTests)
|断言失败:
assert item.save()!= null
| | |
| null false
bugdemo.Item :(未保存)
|打包Grails应用程序.....
需要模拟Joda类的某些方面吗? ?当控制器说
def itemInstance = new Item(params)
为什么它在dev中工作,但没有测试? 在开发中是如何工作的?
我使用Grails 2.2.3,Java 1.7.0_25,Windows 7。
单元测试不会自动设置自定义属性编辑器(负责转换域类实例中的submited信息)。 b
$ b
查看源代码,似乎 JodaTimePropertyEditorRegistrar 负责。所以在你的测试中,你可以使用 defineBeans
来添加这个Spring Bean:
import grails.plugin.jodatime.binding.JodaTimePropertyEditorRegistrar
$ b $ class MyTest {
@Before
public void setup(){
defineBeans {
jodaTimePropertyEditorRegistrar( JodaTimePropertyEditorRegistrar)
}
}
}
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.
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)
}
}
}
这篇关于Grails控制器单元测试Joda时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!