如何在Spock控制器测试中Mock Grails request对象的getReader方法
解决方案
方案1:构造真实非法UTF-8请求体(推荐)
不需要Mock方法,直接构造包含无效UTF-8序列的请求体,完全贴合真实运行场景,代码如下:
import java.nio.charset.MalformedInputException def "测试非UTF-8请求体触发MalformedInputException"() { given: // 构造无效UTF-8字节序列,0xFF不属于合法UTF-8单字节编码范围 byte[] invalidUtf8Bytes = [0xFF as byte] request.content = invalidUtf8Bytes request.characterEncoding = "UTF-8" when: // 调用你的控制器方法 controller.yourTargetMethod() then: thrown(MalformedInputException) }
方案2:对已注入的request实例打桩
如果必须通过Mock getReader() 方法实现,可以直接针对测试框架自动注入到控制器的request实例打桩,代码如下:
import java.nio.charset.MalformedInputException def "Mock getReader方法抛出MalformedInputException"() { given: // 对当前测试上下文已存在的request实例打桩 GroovySpy(request, global: false) { getReader() >> { throw new MalformedInputException(1) } } when: // 调用你的控制器方法 controller.yourTargetMethod() then: thrown(MalformedInputException) }
原有方案失效原因
- 第一个方案自行实例化的
GrailsMockHttpServletRequest没有绑定到当前测试的控制器,Grails测试框架会自动创建并注入专属的request实例,自定义实例不会被调用,因此打桩不生效。 - 第二个方案的全局
GroovySpy仅对Spy定义后新创建的实例生效,测试框架在测试初始化阶段就已经完成了request实例的创建和注入,因此Spy拦截不到已存在的request实例,打桩逻辑不会触发。
内容的提问来源于stack exchange,提问作者Zorobay
相关产品推荐
相关产品推荐

