これらをモックする簡単な方法の 1 つは、が呼び出されたRequestContextHolder
ときにモックを返すようにメタ クラスを変更することです。getRequestAttributes()
これを行うための簡単な仕様を書き上げましたが、うまくいかなかったときはかなり驚きました! したがって、これは非常に興味深い問題であることが判明しました。いくつかの調査の結果、この特定のケースでは、注意すべきいくつかの落とし穴があることがわかりました。
リクエスト オブジェクトを取得するときは、メソッドを実装していないRCH.requestAttributes.request
インターフェイスを介して取得しています。返されたオブジェクトが実際にこのプロパティを持っている場合、これは groovy ではまったく問題ありませんが、spock でインターフェイスをモックする場合は機能しません。したがって、実際にこのメソッドを持つインターフェイスまたはクラスをモックする必要があります。RequestAttributes
getRequest()
RequestAttributes
1. を解決するための私の最初の試みは、モック タイプをメソッドServletRequestAttributes
を持つに変更することでしたgetRequest()
。ただし、この方法は最終的なものです。final メソッドの値でモックをスタブ化すると、スタブ化された値は単純に無視されます。この場合、null
返品されました。
これらの問題は両方とも、このテスト用に というカスタム インターフェースを作成し、MockRequestAttributes
このインターフェースを仕様のモックに使用することで簡単に克服できます。
これにより、次のコードが生成されました。
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
}
}