Grails Spock为SQL注入编写单元/集成测试用例

时间:2015-04-10 09:29:27

标签: unit-testing grails gorm spock

支持REST API的未来更改,允许使用/ query端点查询数据库,并使用JSON作为I / O的数据格式,开始记下测试用例。

我的配置是: -

  1. Grails 2.3.8
  2. Spock测试框架
  3. 我担心,如果我们得到Spock的一些好的支持,可以为SQL注入验证编写测试用例,并且可以达到通用的水平。

    当我们说泛型时,它意味着它应该在每次运行时命中一个不同的端点。 例如,

    1st run : /api/users/query 
    2nd run : /api/group/query
    3rd run : /api/users/query
    .
    .
    nth time : /api/specs/query
    

    因此,每次选择的域名必须不同。我们可以生成一些随机数,用于从所有域的地图或查询端点网址列表中识别域端点。

    但我想到的另一个想法是,是否可以使用另一个测试用例来调用这些测试用例(检查每次运行中不同端点的SQL注入)指定的次数,以便进一步更准确地测试它

2 个答案:

答案 0 :(得分:1)

每次点击一个不同的端点你可以做的是创建一个URLMappings列表,并且每次都可以从列表中获取一个随机控制器。

如果您没有使用自定义urlmappings,那么您可以遍历所有控制器类并可以获取其操作。但是,当你有一个休息api时,我假设你在URLMappings.groovy文件中定义了自定义映射。在这种情况下,在UrlMappingsArtefactHandler的帮助下,您可以获取url mappings工件。代码是:

import org.codehaus.groovy.grails.commons.UrlMappingsArtefactHandler
import org.codehaus.groovy.grails.web.mapping.DefaultUrlMappingEvaluator
import org.codehaus.groovy.grails.web.mapping.UrlMapping
import org.springframework.mock.web.MockServletContext

private List<UrlMapping> getAllURLMappings(){
    ClassLoader classLoader = this.class.classLoader
    def mappings = grailsApplication.getArtefacts(UrlMappingsArtefactHandler.TYPE)

    MockServletContext mctx = classLoader.loadClass('org.springframework.mock.web.MockServletContext').newInstance()
    DefaultUrlMappingEvaluator evaluator = classLoader.loadClass("org.codehaus.groovy.grails.web.mapping.DefaultUrlMappingEvaluator").newInstance(mctx)
    List<UrlMapping> allMappings = []

    List<UrlMapping> grailsClassMappings
    for (mapping in mappings) {
        if (Script.isAssignableFrom(mapping.getClazz())) {
            grailsClassMappings = evaluator.evaluateMappings(mapping.getClazz())
        } else {
            grailsClassMappings = evaluator.evaluateMappings(mapping.getMappingsClosure())
        }
        allMappings.addAll(grailsClassMappings)
    }
    return allMappings
}

然后从所有映射中获取特定操作的url模式,您可以使用以下方法迭代上面方法返回的结果:

private List<String> getMappingForAction(List<UrlMapping> mappings, String action){
    return mappings.findAll {
        UrlMapping mapping ->
            return mapping.actionName.equals(action)
    }*.urlData.urlPattern
}

使用java.util.Random类,您每次都可以获取一个随机端点:

List<UrlMapping> allMappings = getAllURLMappings()
List<String> mappings = getMappingForAction(allMappings, "query")

int size = mappings.size()

Random r = new Random()
int index = r.nextInt(size - 0)

println mappings[index]

答案 1 :(得分:0)

如果您想要使用Spock将一系列参数从一个测试执行更改为下一个测试执行相同的测试,那么您应该考虑使用parameterization使用Spock where blocks。< / p>

下面显示的示例来自Spock文档,但您可以轻松地将参数更改为您要测试的端点数组。

def "computing the maximum of two numbers"() {
  expect:
  Math.max(a, b) == c

  where:
  a << [5, 3]
  b << [1, 9]
  c << [5, 9]
}