在spock test where block中抛出MissingPropertyException

时间:2015-07-17 10:31:02

标签: unit-testing groovy spock

我一直在使用spock对我的java项目进行单元测试,并遇到了问题。我有一个实用程序方法来从http请求获取参数,或者如果http请求为null并且我尝试使用spock测试它,则使用空字符串。我的测试看起来像这样:

package foo.bar.test

import foo.bah.HttpRequestPropertyLoader
import spock.lang.Unroll
import javax.servlet.http.HttpServletRequest
import spock.lang.Specification

class HttpRequestPropertyLoaderTest extends Specification {

    HttpRequestPropertyLoader subjectUnderTest
    def result

    def setup() {
        subjectUnderTest = new HttpRequestPropertyLoader()
    }

    @Unroll("When my http request is #nullOrNot then when I get parameter from it the response=#response" )
    def "Test load data from request"() {
        given:
        HttpServletRequest mockHttpRequest = Mock()
        mockHttpRequest.getAttribute("foo") >> "bar"
        when:
        result = subjectUnderTest.loadStringFromHttpRequest(httpRequest, "foo")
        then:
        result == response
        where:
        httpRequest     | response | nullOrNot
        null            |  ""      | "null"
        mockHttpRequest | "bar"    | "not null"
    }
}

但是,当我运行此测试时,我收到以下错误:

groovy.lang.MissingPropertyException: No such property: mockHttpRequest for class: foo.bar.test.HttpRequestPropertyLoaderTest at foo.bar.test.HttpRequestPropertyLoaderTest.Test load data from request(HttpRequestPropertyLoaderTest.groovy)

在做了一些研究之后,我知道where块在given块之前运行,因此出现错误,但只是想知道是否有解决方法?

我知道要在测试之外使用变量,我需要使用@Shared注释来注释变量,这对我来说似乎是不好的做法。每个测试都应该完全独立于其他测试,所以不要真的想让一个对象在测试之间保持状态。

是否可以设置Mock对象以任何其他方式从where块返回?

1 个答案:

答案 0 :(得分:4)

根据tim_yates建议查看https://code.google.com/p/spock/issues/detail?id=15#c4,我找到了一个相当优雅的解决方案,并不涉及使用@Shared注释。测试定义现在看起来像这样:

package foo.bar.test

import foo.bah.HttpRequestPropertyLoader
import spock.lang.Unroll
import javax.servlet.http.HttpServletRequest
import spock.lang.Specification

class HttpRequestPropertyLoaderTest extends Specification {

    HttpRequestPropertyLoader subjectUnderTest
    def result

    def setup() {
        subjectUnderTest = new HttpRequestPropertyLoader()
    }

    @Unroll("When my http request is #nullOrNot then when I get parameter from it the response=#response" )
    def "Test load data from request"() {
        when:
        result = subjectUnderTest.loadStringFromHttpRequest(httpRequest, "foo")
        then:
        result == response
        where:
        httpRequest << {
            HttpServletRequest mockHttpRequest = Mock()
            mockHttpRequest.getAttribute("foo") >> "bar"
            [null, mockHttpRequest]
        }()
        response << ["", "bar"]
        nullOrNot << ["null", "not null"]
    }
}