I have been using spock for a while to unit test my java project, and have ran into a problem. I have a utility method to get a parameter from a http request, or an empty string if the http request is null and am trying to test it with spock. My test looks like this:
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"
}
}
However, when I run this test, I get the following error:
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)
After doing some research, I understand that the where
block is run before the given
block, hence the error, but was just wondering if there was a workaround?
I know that to use a variable from outside the test, I would need to annotate the variable with the @Shared
annotation, which seems bad practice to me. Every test should run completely separate from the others, so don't really want to have an object that keeps it's state between tests.
Is it possible to setup Mock objects to be returned from the where block any other way?
Following tim_yates suggestion to take a look at https://code.google.com/p/spock/issues/detail?id=15#c4, I found a fairly elegant solution that doesn't involve using the @Shared
annotation. The test definition now looks like this:
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"]
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With