Unit testing spock测试中抛出MissingPropertyException,其中块
我已经使用spock对我的java项目进行了一段时间的单元测试,但遇到了一个问题。我有一个实用程序方法可以从http请求中获取参数,如果http请求为null并且正在尝试使用spock测试它,则可以获取空字符串。我的测试如下所示:Unit testing spock测试中抛出MissingPropertyException,其中块,unit-testing,groovy,spock,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 i
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"
}
}
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"]
}
}
但是,当我运行此测试时,出现以下错误:
groovy.lang.MissingPropertyException:没有这样的属性:mockHttpRequest for class:foo.bar.test.HttpRequestPropertyLoaderTest位于foo.bar.test.HttpRequestPropertyLoaderTest的类:foo.bar.test.HttpRequestPropertyLoaderTest(HttpRequestPropertyLoaderTest.groovy)
在做了一些研究之后,我了解到where
块在给定的块之前运行,因此出现了错误,但我只是想知道是否有解决方法
我知道要在测试之外使用变量,我需要用@Shared
注释对变量进行注释,这在我看来是一种糟糕的做法。每个测试都应该完全独立于其他测试运行,所以我不想让一个对象在测试之间保持它的状态
是否可以通过其他方式设置从where块返回的模拟对象?根据tim_yates的建议,我找到了一个相当优雅的解决方案,它不需要使用@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"() {
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"
}
}
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"]
}
}
package foo.bar.test
导入foo.bah.HttpRequestPropertyLoader
导入spock.lang.Unroll
导入javax.servlet.http.HttpServletRequest
导入spock.lang.Specification
类HttpRequestPropertyLoaderTest扩展了规范{
HttpRequestPropertyLoader主题测试
def结果
def设置(){
subjectUnderTest=新的HttpRequestPropertyLoader()
}
@展开(“当我的http请求为#nullOrNot时,当我从中获取参数时,响应=#响应”)
def“来自请求的测试负载数据”(){
什么时候:
结果=subjectUnderTest.loadStringFromHttpRequest(httpRequest,“foo”)
然后:
结果==响应
哪里:
httpRequest>“条”
[null,mockHttpRequest]
}()
响应您是否尝试过移动HttpServletRequest mockHttpRequest=Mock()
到一个设置
块开始测试时?@tim_yates谢谢你的建议。我刚刚尝试用一个设置块替换给定的块,如果这是你的意思,并得到了相同的结果。四处搜索,我想你需要将你的模拟类移出到一个@共享
类级字段:@tim_yates是的,我看到了e@Shared
注释之前,但正如其中一个答案所说,“缺点是a和o在某种意义上定义在错误的范围内,也可能被其他特性方法使用。”正如我在编辑中所说,这对我来说似乎是一种不好的做法,但如果没有其他选择,我将不得不研究它。我想你可能会移动b将为httpRequest
创建模拟值列表的锁锁定到一个单独的static
方法中,并且只在where
块中调用它。然后它应该更干净、更可读,类似于httpRequest它可以工作!非常好的回答:)