Search code examples
cucumberbddcucumber-javascenarios

Cucumber V5-V6 - passing complex object in feature file step


So I have recently migrated to v6 and I will try to simplify my question

I have the following class

@AllArgsConstructor
public class Songs {
    String title;
    List<String> genres;
}

In my scenario I want to have something like:

Then The results are as follows:
|title      |genre         |
|happy song |romance, happy|

And the implementation should be something like:

@Then("Then The results are as follows:")
public void theResultsAreAsFollows(Songs song) { 
//Some code here
}

I have the default transformer

@DefaultParameterTransformer
    @DefaultDataTableEntryTransformer(replaceWithEmptyString = "[blank]")
    @DefaultDataTableCellTransformer
    public Object transformer(Object fromValue, Type toValueType) {
        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.convertValue(fromValue, objectMapper.constructType(toValueType));
}

My current issue is that I get the following error: Cannot construct instance of java.util.ArrayList (although at least one Creator exists)

How can I tell cucumber to interpret specific cells as lists? but keeping all in the same step not splitting apart? Or better how can I send an object in a steps containing different variable types such as List, HashSet, etc.

If I do a change and replace the list with a String everything is working as expected


Solution

  • @M.P.Korstanje thank you for your idea. If anyone is trying to find a solution for this here is the way I did it as per suggestions received. Inspected to see the type fromValue has and and updated the transform method into something like:

    if (fromValue instanceof LinkedHashMap) {
            Map<String, Object> map =  (LinkedHashMap<String, Object>) fromValue;
            Set<String> keys = map.keySet();
    
            for (String key : keys) {
              if (key.equals("genres")) {
                  List<String> genres = Arrays.asList(map.get(key).toString().split(",", -1));
                  map.put("genres", genres);
              }
                return objectMapper.convertValue(map, objectMapper.constructType(toValueType));
            }
        }
    

    It is somehow quite specific but could not find a better solution :)