marzocchi
marzocchi

Reputation: 75

How to test values and keys of LinkedHashMap?

I wrote method which put chars of a string into LinkedHashMap as a key and quantity of that chars as value, but I don't know how can I test if this method properly count chars.

LinkedHashMap<Character, Integer> map = new LinkedHashMap<>();
for (int i = 0; i < string.length(); i++) {
    char wordToLetter = string.toLowerCase().charAt(i);
    if (map.containsKey(wordToLetter)) {
        int quantity = map.get(wordToLetter);
        map.put(wordToLetter, ++quantity);
    } else {
        map.put(wordToLetter, 1);
    }
}
return map;

Example of input : "abc de"

and as test I want to check if I have a char "a" with proper quantity 1.

Upvotes: 1

Views: 1822

Answers (4)

user8280225
user8280225

Reputation:

Approach to testing without JUnit

The way to check a method is to call it from another method and compare results with some verification method or pre-known expected value. In this case, without junit, it might look like this:

public class Test {
    public static void main(String[] args) {
        String str = "abc de";

        Map<Character, Integer> map = stringToMap(str);
        Map<Character, Integer> mapTest = stringToMapTest(str);

        // visual comparison
        System.out.println(map);      // {a=1, b=1, c=1,  =1, d=1, e=1}
        System.out.println(mapTest);  // {a=1, b=1, c=1,  =1, d=1, e=1}

        // automated comparison
        System.out.println(map.equals(mapTest));                // true

        // step-by-step comparison
        System.out.println(map.getOrDefault('a', 0).equals(1)); // true
        System.out.println(map.getOrDefault('b', 0).equals(1)); // true
    }

    private static Map<Character, Integer> stringToMap(String str) {
        LinkedHashMap<Character, Integer> map = new LinkedHashMap<>();
        for (int i = 0; i < str.length(); i++) {
            char wordToLetter = str.toLowerCase().charAt(i);
            if (map.containsKey(wordToLetter)) {
                int quantity = map.get(wordToLetter);
                map.put(wordToLetter, ++quantity);
            } else {
                map.put(wordToLetter, 1);
            }
        }
        return map;
    }

    private static Map<Character, Integer> stringToMapTest(String str) {
        return str.chars()
                .mapToObj(ch -> (char) ch)
                .collect(Collectors.toMap(
                        ch -> ch,
                        ch -> 1,
                        Integer::sum,
                        LinkedHashMap::new));
    }
}

Upvotes: 0

WJS
WJS

Reputation: 40062

Here is one way to test the characters. It does not use Junit but could be easily adapted.

Random r = new Random();
// save the seed for repeated testing below
long seed = r.nextLong();
r.setSeed(seed);

// supplier to get the next count of letters between 5 and 14 chars
Supplier<Integer> rnd = () -> r.nextInt(10) + 5;

Now generate the test string using the a set of letters.

String letters = "abcdefg";
// this just concatenates varying lengths of the test characters
String testString = letters.chars()
        .mapToObj(ch -> ((char) ch + "").repeat(rnd.get()))
        .collect(Collectors.joining(""));

Now call your method to get the do the count.

Map<Character, Integer> freq = countChars(testString);

Now perform the test. Re-seed the random number and compare the known counts of the letters to those computed.

r.setSeed(seed);
for (char ch : letters.toCharArray()) {
    System.out.printf("Count for '%s' %s%n", ch,
            (freq.get(ch) == rnd.get()) ? "passes" :
                    "does not pass");
}

For counting method it prints

Count for 'a' passes
Count for 'b' passes
Count for 'c' passes
Count for 'd' passes
Count for 'e' passes
Count for 'f' passes
Count for 'g' passes

Your code put in a method.

public static Map<Character, Integer> countChars(String string) {
    LinkedHashMap<Character, Integer> map = new LinkedHashMap<>();
    for (int i = 0; i < string.length(); i++) {
        char wordToLetter = string.toLowerCase().charAt(i);
        if (map.containsKey(wordToLetter)) {
            int quantity = map.get(wordToLetter);
            map.put(wordToLetter, ++quantity);
        } else {
            map.put(wordToLetter, 1);
        }
    }
     return map;
}

Upvotes: 0

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 79425

Given below is a way to test it:

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.LinkedHashMap;

public class Main {
    public static void main(String[] args) {
        LinkedHashMap<Character, Integer> charCountMap = output("abc de");
        assertEquals(1, charCountMap.get('a'));
        assertEquals(1, charCountMap.get('b'));
        assertEquals(1, charCountMap.get(' '));
    }

    public static LinkedHashMap<Character, Integer> output(String inputString) {
        LinkedHashMap<Character, Integer> map = new LinkedHashMap<>();
        for (int i = 0; i < inputString.length(); i++) {
            char wordToLetter = inputString.toLowerCase().charAt(i);
            if (map.containsKey(wordToLetter)) {
                int quantity = map.get(wordToLetter);
                map.put(wordToLetter, ++quantity);
            } else {
                map.put(wordToLetter, 1);
            }
        }
        return map;
    }
}

If you put a different value e.g. assertEquals(2, charCountMap.get('a'));, it will throw AssertionFailedError exception.

Upvotes: 1

maveriq
maveriq

Reputation: 516

here is the test example for your case:

package your.package.here;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.collection.IsMapContaining.hasEntry;

import java.util.Map;
import org.junit.Test;

public class MainTest {

  @Test
  public void testMapContent() {
    String input = "abc de";
    Integer aExpectedCount = 1;

    Map<Character, Integer> generatedMap = Main.generateMap(input);

    assertThat(generatedMap, hasEntry('a', aExpectedCount));
  }
}

and the Main class:

package your.package.here;

import java.util.LinkedHashMap;
import java.util.Map;

public class Main {  

  public static Map<Character, Integer> generateMap(String string) {
    LinkedHashMap<Character, Integer> map = new LinkedHashMap<>();
    for (int i = 0; i < string.length(); i++) {
      char wordToLetter = string.toLowerCase().charAt(i);
      if (map.containsKey(wordToLetter)) {
        int quantity = map.get(wordToLetter);
        map.put(wordToLetter, ++quantity);
      } else {
        map.put(wordToLetter, 1);
      }
    }
    return map;
  }
}

Upvotes: 1

Related Questions