Auto‑Generating Java API Test Code from Swagger JSON

This article explains how to parse a Swagger JSON document and automatically generate maintainable Java test code for each API endpoint, detailing the handling of GET query parameters, POST form‑data, RESTful path variables, and header conventions.

FunTester
FunTester
FunTester
Auto‑Generating Java API Test Code from Swagger JSON

Refactoring the request generation logic

The original monolithic magic() method was decomposed into a set of small, focused methods. This improves readability, testability, and future maintenance.

Generating test code from Swagger

A Swagger contract is used as the single source of truth: GET endpoints use query parameters, POST endpoints use form‑data (except file uploads), and shared parameters are placed in headers. The Swagger JSON is parsed to build Request objects, which are then converted into ready‑to‑run Java test methods.

package com.fission.source.until;

import com.fission.source.profile.Constant;
import com.fission.source.source.SourceCode;
import lombok.Data;
import net.sf.json.JSONObject;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Data
public class Request extends SourceCode {
    private String url;                 // request URL
    private String type;                // GET / POST
    private String apiName;              // method name
    private String desc;                 // description
    List<String> restfulArgs = new ArrayList<>(); // {id} placeholders
    JSONObject args = new JSONObject();          // query parameters
    JSONObject params = new JSONObject();        // form‑data parameters
    StringBuffer stringBuffer = new StringBuffer(); // method signature builder
    StringBuffer code = new StringBuffer();        // generated method body
    boolean postNoParams = false;      // true when POST has no body

    /** Append JSON argument creation code */
    private void spliceArgs(int i) {
        String type = i == 1 ? "params" : "args";
        code.append(LINE + TAB + TAB + "JSONObject " + type + " = new JSONObject();");
        Set keySet = i == 0 ? args.keySet() : params.keySet();
        keySet.forEach(key -> {
            collectArgs(key.toString(), (i == 0 ? args : params).getString(key.toString()));
            code.append(LINE + TAB + TAB + type + ".put(\"" + key + "\", " + key + ");");
        });
    }

    /** Build method‑parameter fragment based on Swagger type */
    private void collectArgs(String key, String value) {
        if (value.equals("string")) stringBuffer.append("String " + key + ",");
        if (value.equals("integer")) stringBuffer.append("int " + key + ",");
    }

    /** Extract RESTful placeholders from the URL */
    private void collectRestfulArgs() {
        if (url.contains("{")) {
            List<String> placeholders = regexAll(url, "\\{[^}]+\\}");
            placeholders.forEach(p -> restfulArgs.add(p.replace("{", "").replace("}", "")));
        }
    }

    /** Build the URL string, inserting placeholders as method parameters */
    private String spliceUrl() {
        collectRestfulArgs();
        url = url.contains("{") ? url : url + "\"";
        url = "\"" + url.replace("}/{", "+OR+").replace("{", "\"+").replace("}", "") + "\"";
        return TAB + TAB + "String url = HOST + " + url + ";";
    }

    /** Generate GET request code */
    private void spliceGet() {
        if (!args.isEmpty()) {
            spliceArgs(0);
            code.append(LINE + TAB + TAB + "HttpGet httpGet = getHttpGet(url, args);");
        } else {
            code.append(LINE + TAB + TAB + "HttpGet httpGet = getHttpGet(url);");
        }
        code.append(LINE + TAB + TAB + "JSONObject response = getHttpResponse(httpGet);");
    }

    /** Generate POST request code */
    private void splicePost() {
        if (!args.isEmpty()) spliceArgs(0);
        if (!params.isEmpty()) spliceArgs(1);
        if (args.isEmpty()) {
            if (!params.isEmpty()) {
                code.append(LINE + TAB + TAB + "HttpPost httpPost = getHttpPost(url, params);");
            } else {
                code.append(LINE + TAB + TAB + "HttpPost httpPost = getHttpPost(url);");
            }
        } else {
            if (!params.isEmpty()) {
                code.append(LINE + TAB + TAB + "HttpPost httpPost = getHttpPost(url, args, params);");
            } else {
                postNoParams = true;
            }
        }
        code.append(LINE + TAB + TAB + "JSONObject response = getHttpResponse(httpPost);");
    }

    /** Finalise method body */
    private String spliceEnd() {
        restfulArgs.forEach(a -> stringBuffer.append("int " + a + ","));
        code.append(LINE + TAB + TAB + "output(response);");
        code.append(LINE + TAB + TAB + "return response;");
        code.append(LINE + TAB + "}");
        return code.toString()
                .replace("() {", "(" + stringBuffer.toString() + ") {")
                .replace(",)", ")");
    }

    /** Convert the request definition into a Java method */
    public String magic() {
        code.append(TAB + "/**
 * " + desc + "
 */" + LINE);
        code.append(TAB + "public JSONObject " + apiName + "() {" + LINE);
        String urlLine = spliceUrl();
        code.append(urlLine);
        if (type.equals(REQUEST_TYPE_GET)) spliceGet();
        if (type.equals(REQUEST_TYPE_POST)) splicePost();
        String finalCode = spliceEnd();
        if (postNoParams) {
            finalCode = finalCode.replace(urlLine, urlLine.replace(";", "") + " + changeJsonToArguments(args)");
        }
        output(finalCode);
        return finalCode;
    }
}

Swagger parser

The Swagger class reads a Swagger JSON document, extracts module names, URLs, and parameter definitions, and creates a list of Request objects for a selected module.

package com.fission.source.until;

import com.fission.source.source.ApiLibrary;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class Swagger extends ApiLibrary {
    String key;               // prefix before the URL path
    String swaggerPath;       // location of swagger.json
    String name;             // module name selected by the user
    String url;              // optional single endpoint URL
    List<String> names = new ArrayList<>(); // all module names
    List<String> urls = new ArrayList<>();  // all endpoint paths
    JSONObject swagger = new JSONObject();   // whole swagger document
    JSONObject paths = new JSONObject();     // "paths" node
    Request request = new Request();
    List<Request> requests = new ArrayList<>();

    public static void main(String[] args) {
        String surl = "http://10.10.32.158:6005/swagger.json";
        String sname = "Guild Initial Module";
        Swagger swagger = new Swagger(surl, sname);
        swagger.requests.forEach(r -> r.magic());
        testOver();
    }

    public Swagger(String swaggerPath, String name) {
        this.swaggerPath = swaggerPath;
        this.name = name;
        build();
    }

    /** Initialise parsing and object creation */
    public void build() {
        swagger = getHttpResponse(getHttpGet(swaggerPath));
        getKey();
        getNames();
        getPaths();
        getUrls();
        getRequests();
    }

    private void getKey() {
        key = regexAll(swaggerPath, "/((?!/).)*/swagger.json").get(0)
                .replace(OR, "").replace("swagger.json", "");
        if (key.contains(":")) key = "";
    }

    private void getNames() {
        JSONArray tags = swagger.getJSONArray("tags");
        tags.forEach(t -> names.add(((JSONObject) t).getString("name")));
    }

    private void getPaths() {
        paths = swagger.getJSONObject("paths");
    }

    private void getUrls() {
        Set keySet = paths.keySet();
        keySet.forEach(k -> urls.add(k.toString()));
    }

    private void getRequests() {
        urls.forEach(u -> {
            Request r = getRequest(u);
            if (r != null) requests.add(r);
        });
    }

    /** Create a Request object for a specific endpoint */
    private Request getRequest(String url) {
        Request req = new Request();
        req.setUrl((OR + key + url).replace("//", "/"));
        JSONObject node = paths.getJSONObject(url);
        JSONObject operation = null;
        if (node.containsKey("get")) {
            req.setType(REQUEST_TYPE_GET);
            operation = node.getJSONObject("get");
        } else if (node.containsKey("post")) {
            req.setType(REQUEST_TYPE_POST);
            operation = node.getJSONObject("post");
        }
        if (operation == null) return null;
        if (!operation.getString("tags").contains(name)) return null;
        req.setApiName(operation.getString("operationId"));
        req.setDesc(operation.getString("summary"));
        JSONArray parameters = operation.getJSONArray("parameters");
        JSONObject query = new JSONObject();
        JSONObject form = new JSONObject();
        parameters.forEach(p -> {
            JSONObject param = (JSONObject) p;
            String in = param.getString("in");
            if (in.equals("query") && param.getBoolean("required")) {
                query.put(param.getString("name"), param.getString("type"));
            } else if (in.equals("formData") && param.getBoolean("required")) {
                form.put(param.getString("name"), param.getString("type"));
            }
        });
        req.setArgs(query);
        req.setParams(form);
        return req;
    }
}

Key implementation details

RESTful placeholders such as {id} are detected with a regular expression and turned into method parameters.

Swagger parameters entries are classified into query arguments ( args) and form‑data arguments ( params) based on the in field.

Parameter types are mapped to Java types: stringString, integerint. The generated method signature is built dynamically.

Header handling and response output ( output(response)) are inserted automatically.

If a POST endpoint has no form‑data, the query string is appended directly to the URL (controlled by postNoParams).

Usage

Running the main method of Swagger reads the Swagger document, creates a Request for each endpoint in the selected module, and calls magic(). The result is a Java method per API that can be used directly in automated tests, eliminating repetitive hand‑coding.

Consistent Swagger contracts are required; mismatches between the contract and the actual service will produce incorrect generated code.

Generated Java test code screenshot
Generated Java test code screenshot
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendJavaCode GenerationAutomationSwaggerAPI testing
FunTester
Written by

FunTester

10k followers, 1k articles | completely useless

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.