I am working with Java Spark and Groovy Spock for testing. I am currently trying to test queryParams from an URI but i can't seem to figure it out.
Actually i have a few tests working for testing path params like this:
import spark.Request
import spark.routematch.RouteMatch
import spock.lang.Shared
import spock.lang.Specification
class ChargeRouterValidatorSpec extends Specification {
@Shared
HttpServletRequest servletRequest = Mock(HttpServletRequest.class)
@Shared
Request request
void "test"() {
given:
RouteMatch match = new RouteMatch(null, "/charges/:id", "/charges/1" , "text/html")
request = new Request(match, servletRequest)
when:
def test = request.params("id")
then:
test == "1"
}
}
Spark Request uses changeMatch method which splits the first URI string from RouteMatch in '/' as well as the second URI string, compares and gets params which match the position of split parts that begin with ':'
That works perfect and test evaluates to 1.
Now, when i try to test queryParams
import spark.Request
import spark.routematch.RouteMatch
import spock.lang.Shared
import spock.lang.Specification
class ChargeRouterValidatorSpec extends Specification {
@Shared
HttpServletRequest servletRequest = Mock(HttpServletRequest.class)
@Shared
Request request
void "test"() {
given:
RouteMatch match = new RouteMatch(null, "/charges/:id", "/charges/1?test=test" , "text/html")
request = new Request(match, servletRequest)
when:
def test = request.queryParams("test")
then:
test == "test"
}
}
Test is always null.
My question is how should i correctly test for queryParams?
I want to add that when i run locally and try it, queryParams evaluates correctly but i can't make tests depending on a server.
I have found a solution. Spock has a similar function to Mockito when().thenReturn() which is mock.method(param) >> wantedResult
So the test looks like this:
import spark.Request
import spark.routematch.RouteMatch
import spock.lang.Shared
import spock.lang.Specification
class ChargeRouterValidatorSpec extends Specification {
@Shared
HttpServletRequest servletRequest = Mock(HttpServletRequest.class)
@Shared
Request request
void "test"() {
given:
RouteMatch match = new RouteMatch(null, "/charges/:id", "/charges/1" , "text/html")
request = new Request(match, servletRequest)
when:
servletRequest.getParameter("test") >> "test"
def test = request.queryParams("test")
then:
test == "test"
}
}
This evaluates correctly.
I sustain my criticism of your test. It is meaningless because you are just testing that method Request.queryParams(String)
returns the value you define to be returned by your mock or stub. Furthermore, you create the Request
using a package-protected constructor, which only works because you are using Groovy. Here is the relevant part of the class under test:
package spark;
// (...)
public class Request {
// (...)
private HttpServletRequest servletRequest;
// (...)
Request(RouteMatch match, HttpServletRequest request) {
this.servletRequest = request;
changeMatch(match);
}
public String queryParams(String queryParam) {
return servletRequest.getParameter(queryParam);
}
// (...)
}
See? You are just testing that the mock can return a mock result. And why are you unit-testing a third-party class anyway? This makes no sense whatsoever, unless your sample code is not your real test but just s small part of a bigger test and you are actually testing something else (one of your own classes) and just need the mock result for something else. But as given, the test is just nonsense.
Anyway, for what it is worth, a few hints about your test structure:
Why use @Shared
? The beauty of Spock is that instance variables are not shared by default so as to avoid side effects and dependencies between tests. Even worse, the code in your own, accepted solution fails unless you remove @Shared
altogether. I tried. You should be more cautious about posting answers to your own questions which do not even work and then even accepting them.
You have two test cases, but only posted an answer for one of them, but not even the one you had problems with before.
The two test cases are also very similar in structure, the only thing which is different is the request URI for the RouteMatch
. I suggest you use a parametrised test with where:
and @Unroll
for this case. It gets rid of duplicate code and with a few renames for the test and variable names is more readable.
package de.scrum_master.stackoverflow
import spark.Request
import spark.routematch.RouteMatch
import spock.lang.Specification
import spock.lang.Unroll
import javax.servlet.http.HttpServletRequest
class SparkJavaTest extends Specification {
@Unroll
def "Request returns expected value for query parameter '#requestUri'"() {
given:
def routeMatch = new RouteMatch(null, "/charges/:id", requestUri, "text/html")
def servletRequest = Stub(HttpServletRequest) {
getParameter("test") >> "test"
}
def request = new Request(routeMatch, servletRequest)
expect:
request.queryParams("test") == "test"
where:
requestUri << ["/charges/1", "/charges/1?test=test"]
}
}
BTW, whether you use Mock()
or Stub()
in the example above, is up to you.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.