简体   繁体   中英

Grails Spock writing unit / integration test case for SQL injections

To support future changes in REST API that that allows query the database using /query endpoint and uses JSON as data format for I/O starting to write down test cases.

My configs are:-

  1. Grails 2.3.8
  2. Spock testing framework

I'm concerned if we have some good support from Spock for writing test cases for SQL injections verification and up to what level generic it can be made.

When we say generic, it means that it should be hitting a different endpoint each time it is run. For example,

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

So, the domain chosen must be different each time. We can have some random number generated which can be used to identify Domain endpoint from a map or list of query endpoint urls for all domains.

But next thought comes to my mind is whether there could another test case in place that can call these test cases(that check for SQL injections for different endpoints on each run) a specified number of times to test it further and more accurately.

For hitting a different endpoint each time what you can do is create a list of URLMappings and can fetch a random controller each time from list.

If you are not using custom urlmappings then you can iterate over all controller classes and can fetch their actions. But as you have a rest api, I'm assuming you have custom mappings defined in URLMappings.groovy file. In this case with the help of UrlMappingsArtefactHandler you can get the url mappings artifacts. Code for that would be:

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
}

Then to fetch url patterns for a specific action from all mappings you can iterate over the result returned from above method using below method:

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

And using java.util.Random class you can fetch a random endpoint each time:

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]

If you're wanting to run the same test with a series of parameters that change from one test execution to the next using Spock, then you should consider using parameterization using Spock where blocks .

The example shown below is from the Spock documentation, but you could easily change the parameter to be an array of endpoints you wish to test.

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

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

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM