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?
HttpServletRequest mockHttpRequest = Mock()
to asetup
block at the start of your test? – Susurrous@Shared
class level field – Susurrous@Shared
annotation before, but as one of the answers says 'The downside is that a and o are in a sense defined in the wrong scope and could be used by other feature methods as well.' As I have said in my edit, this seems like bad practice to me, but if there is no alternative, I will have to look into it. – Moua