加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

unit-testing – 如何在grails中单元测试服务时模拟请求

发布时间:2020-12-14 16:33:31 所属栏目:大数据 来源:网络整理
导读:我正在尝试对具有需要请求对象的方法的服务进行单元测试. import org.springframework.web.context.request.RequestContextHolder as RCHclass AddressService { def update (account,params) { try { def request = RCH.requestAttributes.request // retri
我正在尝试对具有需要请求对象的方法的服务进行单元测试.

import org.springframework.web.context.request.RequestContextHolder as RCH

class AddressService {

    def update (account,params) {
        try {
            def request = RCH.requestAttributes.request
            // retrieve some info from the request object such as the IP ...
            // Implement update logic
        } catch (all) { 
            /* do something with the exception */ 
        }
    }
}

你如何模拟请求对象?

顺便说一句,我正在使用Spock对我的课进行单元测试.

谢谢

解决方法

模拟这些的一种简单方法是修改RequestContextHolder的元类,以便在调用getRequestAttributes()时返回模拟.

我为此做了一个简单的规范,并且当它不起作用时非常惊讶!所以这结果是一个非常有趣的问题.经过一番调查,我发现在这种特殊情况下,有一些陷阱需要注意.

>当您检索请求对象RCH.requestAttributes.request时,您通过未实现getRequest()方法的接口RequestAttributes这样做.如果返回的对象实际上具有此属性,则在groovy中完全正常,但在spock中模拟RequestAttributes接口时将无法工作.因此,您需要模拟实际具有此方法的接口或类.
>我第一次尝试解决1.,是将mock类型更改为ServletRequestAttributes,它具有getRequest()方法.但是,这种方法是最终的.当使用最终方法的值来存储模拟时,简单地忽略存根值.在这种情况下,返回null.

通过为此测试创建一个名为MockRequestAttributes的自定义接口,并在规范中将此接口用于Mock,可以轻松克服这两个问题.

这导致以下代码:

import org.springframework.web.context.request.RequestContextHolder

// modified for testing
class AddressService {

    def localAddress
    def contentType

    def update() {
        def request = RequestContextHolder.requestAttributes.request
        localAddress = request.localAddr
        contentType = request.contentType
    }
}
import org.springframework.web.context.request.RequestAttributes
import javax.servlet.http.HttpServletRequest

interface MockRequestAttributes extends RequestAttributes {
    HttpServletRequest getRequest()
}
import org.springframework.web.context.request.RequestContextHolder
import spock.lang.Specification

import javax.servlet.http.HttpServletRequest

class MockRequestSpec extends Specification {

    def "let's mock a request"() {
        setup:
        def requestAttributesMock = Mock(MockRequestAttributes)
        def requestMock = Mock(HttpServletRequest)
        RequestContextHolder.metaClass.'static'.getRequestAttributes = {->
            requestAttributesMock
        }

        when:
        def service = new AddressService()
        def result = service.update()

        then:
        1 * requestAttributesMock.getRequest() >> requestMock
        1 * requestMock.localAddr >> '127.0.0.1'
        1 * requestMock.contentType >> 'text/plain'
        service.localAddress == '127.0.0.1'
        service.contentType == 'text/plain'

        cleanup:
        RequestContextHolder.metaClass = null
    }

}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读