Spock - 存根JSON响应

时间:2017-03-08 21:40:45

标签: java unit-testing grails groovy spock

我使用内置spock的Grails 3.1.7。看起来我遇到了在单元测试执行期间存根由控制器呈现的服务返回值的问题。 Service方法返回null,然后控制器抛出GroovyRuntimeException,因为返回“null”而抱怨“无法解析要调用的方法”。

控制器动作代码示例:

def register(RequestRegistrationCommand rrc) {
    //some logic
    render ajaxResponseService.composeJsonResponse(rrc)
}

服务方法代码示例:

JSON composeJsonResponse(instance, String successMessage = null) {
    //some logic
    [success: success, messages: messages] as JSON
}

部分测试套件代码:

//field definitions
def requestRegistrationCommand = Mock(RequestRegistrationCommand)
def ajaxResponseService = Mock(AjaxResponseService)

def setup() {
    controller.ajaxResponseService = ajaxResponseService
    .....
}

void "Testing register() action"() {
    when: 'Passing invalid register params'
    ...
    params.email = INVALID_EMAIL
    controller.register(requestRegistrationCommand)

    then: 'JSON response returned'
    ...
    1 * ajaxResponseService.composeJsonResponse(requestRegistrationCommand) >> [asd:123] as JSON //tried plenty of things here
}

有趣的是,交互本身被触发(通过将其替换为“0 * _”进行检查,并且还将“1 * ajaxR ...>>'asd'”与获取字符串错误不要被转换为JSON)。所以交互可能会返回一些存根值,但无论如何,在大多数情况下,我尝试控制器的行为就好像它试图呈现为null:

  

groovy.lang.GroovyRuntimeException:模糊方法重载   方法   grails.artefact.controller.support.ResponseRenderer $特质$助手#渲染。   无法解析为[class]调用哪个方法   com.tempvs.controllers.AuthController,null]由于重叠   原型之间:[界面   grails.artefact.controller.support.ResponseRenderer,接口   java.lang.CharSequence] [interface   grails.artefact.controller.support.ResponseRenderer,接口   java.util.Map] [接口   grails.artefact.controller.support.ResponseRenderer,接口   org.grails.web.converters.Converter] at   com.tempvs.controllers.AuthController.register(AuthController.groovy:45)     在com.tempvs.controllers.AuthControllerSpec.Testing register()   动作(AuthControllerSpec.groovy:97)

我做错了什么以及如何强制模拟服务对象返回非空值以避免控制器呈现失败?

如果需要更多信息,请通知我,我尽量做到尽可能简短。提前谢谢!

UPD 测试通过互动:

1 * ajaxResponseService.composeJsonResponse(requestRegistrationCommand) >> Mock(JSON)

当我更改AjaxResponseService#composeJsonResponse()时,将返回类型从 JSON 返回到 def 。但是来吧,我只使用一个模拟的合作者进行测试,我怎样才能强制它支持显式类型?!?!

2 个答案:

答案 0 :(得分:1)

您应该使用闭包作为返回值:

1 * ajaxResponseService.composeJsonResponse(requestRegistrationCommand) >> { [asd:123] as JSON }

参见(参见关于返回值的部分):

http://spockframework.org/spock/docs/1.1-rc-3/interaction_based_testing.html

你可以用括号包装回报:

1 * ajaxResponseService.composeJsonResponse(requestRegistrationCommand) >> ( [asd:123] as JSON )

答案 1 :(得分:0)

实际上我通过模拟返回值来解决它:

def json = Mock(JSON)
....
1 * ajaxResponseService.composeJsonResponse(requestRegistrationCommand) >> json