Bank

Get the value from a map in java

I recently created some cucumber tests to test a mapper module in our system. The tests converts data from an input data structure to another data structure.

Scenario: Input data is correctly converted
    Given The input data contains following data
      | id      | year |
      | 123123  | 2020 |
      | 456456  | 2020 |
      | 001122  | 2019 |
    When the mapper transforms the data
    Then the result dossier id is mapped to
      | Dossier ID |
      | 2020123123 |
      | 2020456456 |
      | 2019001122 |

The data is injected in our code with a Datatable. This function parses the lines as a Map and appends it to our inputData variable.

public class DataGlue {
    InputData inputdata;
    @Given("The input data contains following data")
    public void inputDataContainsData(Datatable table){
        inputdata = new InputData();
        List<Map<String, String>> rows = table.asMaps(String.class, String.class);
        for (Map<String,String> line: rows){
            in.appendToHistory(line);
        }
    }
};

Then this input data is converted to the input structure that the mapper transformation functions needs. The function calls the generate function to fetch the input data.

public class InputData {
    Map<String, String> template;
    private final List<Map<String, String>> history;

    public InputData (){
        this.template = new HashMap<>();
        this.template.put("id", "000");
        this.template.put("name", "fake name");
    }

    public void appendToHistory(Map<String,String> item){
        this.history.add(item);
    }
    public InputDataType generate(){
        InputDataType input = new InputDataType();
        for (Map<String, String> data: this.history){
            input.appendId(this.getId(data));
            input.appendName(this.getName(data));
        }
        return input;
    }

    private String getId(Map<String, String> data){
       String value;
       for ( Map.Entry<String, String> entry: data.entrySet()){
           if (entry.getKey().equals("id")){
               value = entry.getValue();
               break;
           }
       }
       if (value == null){
           value = this.template.get("id");
       }
       return value;
    }

    private String getName(Map<String, String> data){
       String value;
       for ( Map.Entry<String, String> entry: data.entrySet()){
           if (entry.getKey().equals("name")){
               value = entry.getValue();
               break;
           }
       }
       if (value == null){
           value = this.template.get("name");
       }
       return value;
    }
};

The code calls the getName and getId functions. These loop over the input data for each key in the Map. If the key matches the key we want, then the value is returned. If the key does not exist a value from an internal template structure is returned.

Now this can be better. I found a function of a Hashmap that fetches the key or if the key does not exist returns a default value. This is exactly what we need ! Let’s refactor it the code.

The getId and getName functions can be rewritten as follows

public class InputData {
    ...

    private String getId(Map<String, String> data){
       return dossier.getOrDefault("id", this.template.get("id"));
    }

    private String getName(Map<String, String> data){
       return dossier.getOrDefault("name", this.template.get("name"));
    }
};

The code is now smaller and easier to read. This is exactly what I want after the refactoring of the code. So the message is that the language supports also some useful functions. Do not write them yourself.

About the author

I currently work as a Test Automation Consultant at b.ignited. Here I work for different clients in different industries to help them start and speed up their testing cycles

I’ve been testing software since 2000 when I became involved in testing telephone applications and hardware. Since then, I’ve been able to expand my experience by testing a variety of embedded, web, mobile and desktop applications. I have used various development methodologies from waterfall to agile.

I consider myself to be a lifelong learner.