【发布时间】:2018-10-25 11:53:34
【问题描述】:
Tl;dr:我想在this code 绿色中测试MyCmdTest."data bind works"。
感谢 Jeff Scott Brown getting me that far。
我有一个 POGO,其中包含一些来自 JSON 的自定义转换,我希望在 Grails 控制器中接收这些转换:
def myAction(MyCmd myData) {
...
}
与:
@Validateable
class MyCmd {
SomeType some
void setSome(Object value) {
this.some = customMap(value)
}
}
请注意 customMap 如何从 JSON 值(例如,字符串)创建 SomeType 的实例。让我们假设默认设置器不起作用;例如,我们不止一次使用的模式是这样的枚举:
enum SomeType {
Foo(17, "foos"),
Bar(19, "barista")
int id
String jsonName
SomeType(id, jsonName) {
this.id = id
this.jsonName = jsonName
}
}
这里,customMap 将接受一个整数或字符串,并返回匹配的大小写(或 null,如果不匹配)。
现在,我有一个如下形式的单元测试:
class RegistrationCmdTest extends Specification {
String validData // hard-coded, conforms to JSON schema
void test() {
MyCmd cmd = new MyCmd(JSON.parse(validData))
// check members: success
MyCmd cmd2 = JSON.parse(validData) as MyCmd
// check members: success
}
}
显然,setSome 在两种变体中都被调用。
我还有一个控制器单元测试,将请求 JSON 设置为相同的字符串:
void "register successfully"() {
given:
ResonseCmd = someMock()
when:
controller.request.method = 'POST'
controller.request.contentType = "application/json"
controller.request.json = validData
controller.myAction()
then:
noExceptionThrown()
// successful validations: service called, etc.
}
基本上同样的事情也作为集成测试运行。
但是,当运行完整的应用程序时,映射失败; some == null。
我必须实现或重写哪些方法,以便 Grails 调用我的转换(此处为 customMap),而不是在它不知道该怎么做的地方插入 null?
【问题讨论】:
-
我在上面提供的链接适用于 Grails 3。在 Grails 2.5.6 中,创建实例的过程完全相同,但发生在 github.com/grails/grails-core/blob/…。 (不同的类,相同的行为)
-
仅供参考...您不必在测试中使用
controller.request.contentType = "application/json",因为您正在执行controller.request.json = validData,这将为您设置内容类型。这发生在github.com/grails/grails-core/blob/v2.5.6/grails-test/src/main/…。 -
@JeffScottBrown 不幸的是,
bindData并没有真正记录在案,甚至很难为它编写单元测试。对DataBindingUtils.bindObjectToInstance进行测试似乎是谨慎的做法,这显然是调用的助手。 -
@JeffScottBrown 恐怕我给人的印象是过于刻薄和不感恩。虽然我经常对 Grails 感到沮丧,但这不应该影响我在这里的交互。所以,对不起,如果我冒犯了。我曾经并且非常感谢您为帮助我而付出的努力! (最后,问题是我没有阅读正确的文档,所以我想我们在那里聊了一会儿。)