How to match a parameter value which contains ("${") using Cucumber DataTable in Java

Viewed 126

I have the below Cucumber scenario with data table. I want to set query parameters in REST Assured framework. Here we have key= at and value=${atToken} which I am trying to get runtime value instead of passing hardcoded value through data table. In the below setParams method, I am trying to match the ${atToken} using param.contains("${"), but I am not able to get the desired result. Please let me know what I need to change in this for loop.

for (String param : params.keySet()) {
    if (param.contains("${")) {
        params.replace(param, RUN_TIME_DATA.get(param));
    }
}

Feature file:

  And I set query parameters
  | location     | NY         |
  | at           | ${atToken} |

Stepdefintion:

@And("set {} parameters")
public void set_query_parameters(String query, DataTable params) throws IOException {
    POC.setParams(query, params.asMap());
}

Utils file:

public void setParams (String type, Map < String, String > params) throws IOException {
    for (String param : params.keySet()) {
        if (param.contains("${")) {
            params.replace(param, RUN_TIME_DATA.get(param));
        }
    }
    switch (type.toLowerCase()) {
        case "form":
            request.formParams(params);
            break;
        case "query":
            request.queryParams(params);
            break;
        case "path":
            request.pathParams(params);
            break;

    }
}

Hooks file:

@Before
public void beforeScenario() throws Exception {
    RUN_TIME_DATA.put("atToken", POC.createAuth());
}
1 Answers

If I understood correctly your quetion, there are a few issues with your implementation.

First of all, you have a gherkin instruction as And I set query parameters but the step definition is @And("set {} parameters")

As you defined "query" in your step definition, I assume that you have a scenario like this.

Scenario Outline: Params scenario
Given ...
When ...
Then ...
    And I set "<queryType>" parameters
      | location | NY         |
      | at       | ${atToken} |
    Examples:
      | queryType |
      | form      |
      | path      |

Second problem is that params.asMap() does not create a mutable map but your setParams method will need a mutable one.

@And("I set {string} parameters")
public void set_query_parameters(String queryType, DataTable params) throws IOException {
    // POC.setParams(queryType, params.asMap()); // not mutable map
    POC.setParams(queryType, new HashMap(params.asMap()));
}

The main issue in your loop was that you were searching $ symbol in key instead of value.

public void setParams (String type, Map<String, String> params) throws IOException {
      for (Map.Entry<String, String> entry : params.entrySet()) {
         final String key = entry.getKey();
         final String value = entry.getValue();

         // if value is parameterized
         if (value.contains("${")) {
            // you are using stripped value as key in your RUN_TIME_DATA
            final String keyInRuntimeMap = getParamKeyFrom(value);                      
            params.replace(key, RUN_TIME_DATA.get(keyInRuntimeMap));
         }
      }

      switch (type.toLowerCase()) {
         case "form":
            request.formParams(params);
            break;
         case "query":
            request.queryParams(params);
            break;
         case "path":
            request.pathParams(params);
            break;
        // what should happen if unknown type given
         default:
            throw new IllegalArgumentException("unknown type=" + type);
      }
   }

     /**
    * Will strip someKey from ${someKey}
    *
    * @param text
    * @return stripped text or the original text
    */
   private String getParamKeyFrom(final String text) {
      // pattern to match -> ${someKey}
      final Pattern pattern = Pattern.compile("\\$\\{(.*)\\}");
      final Matcher matcher = pattern.matcher(text);

      if (matcher.find()) {
         return matcher.group(1);
      }

      // if pattern does not match return the same string
      return text;
   }

Hope it helps.

Related