我正在使用Java Spark和Groovy Spock进行测试。我目前正在尝试从URI测试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" , "text/html")
request = new Request(match, servletRequest)
when:
def test = request.params("id")
then:
test == "1"
}
}
Spark Request使用changeMatch方法,该方法从' /'中的RouteMatch中分割出第一个URI字符串。以及第二个URI字符串,比较并获得与以'开头的分割部分的位置匹配的参数:'
完美无缺,测试评估为1。
现在,当我尝试测试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"
}
}
测试始终为空。
我的问题是我应该如何正确测试queryParams?
我想补充一点,当我在本地运行并尝试时,queryParams会正确评估,但我无法根据服务器进行测试。
答案 0 :(得分:1)
我找到了解决方案。当()。thenReturn()是mock.method(param)>>时,Spock与Mockito有类似的功能。 wantedResult
所以测试看起来像这样:
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"
}
}
这可以正确评估。
答案 1 :(得分:0)
我坚持批评你的考试。它没有意义,因为您只是测试该方法Request.queryParams(String)
返回您定义的值,以便您的模拟或存根返回。此外,您使用受包保护的构造函数创建Request
,该构造函数仅在您使用Groovy时才有效。以下是被测课程的相关部分:
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);
}
// (...)
}
请参阅?您只是测试模拟可以返回模拟结果。那你为什么要对第三方课程进行单元测试呢?这没有任何意义,除非你的示例代码不是你真正的测试,而只是一个更大的测试的一小部分,你实际上正在测试其他东西(你自己的一个类),只需要模拟结果的其他东西。但是如上所述,测试只是无稽之谈。
无论如何,对于它的价值,有关你的测试结构的一些提示:
为什么要使用@Shared
? Spock的优点是默认情况下不共享实例变量,以避免测试之间的副作用和依赖关系。更糟糕的是,除非您完全删除@Shared
,否则您自己接受的解决方案中的代码将失败。我试过了。你应该更加谨慎地发布自己的问题的答案,这些答案甚至不起作用,然后甚至接受它们。
您有两个测试用例,但只发布了其中一个测试用例的答案,但即使是之前遇到问题的答案也没有。
两个测试用例的结构也非常相似,唯一不同的是RouteMatch
的请求URI。对于这种情况,我建议您使用where:
和@Unroll
进行参数化测试。它摆脱了重复的代码,并为测试提供了一些重命名,变量名更具可读性。
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"]
}
}
顺便说一句,无论您在上面的示例中使用Mock()
还是Stub()
,都取决于您。