how to use assertj extracting map property
Asked Answered
S

6

14

I am using AssertJ. I have a class like MyObj. And I have a List of MyObj.

class MyObj {
    ...
    Map<K,V> myMap;
    ...
}

When I use:

  1. assertThat(list).extracting("myMap"), I cannot use .containsKey() method.
  2. I also tried using assertThat(list).extracting("myMap", Map.class), but it does not work either.

What is the right way of using it?

Slipshod answered 25/7, 2015 at 8:24 Comment(4)
Why not just grab the map in a variable and use assertj on that?Dachy
@Dachy It is a way. But I am wondering is there any easier way to extract map property directly.Slipshod
Extracting a Map property from a list of objects allows doing assertions on a list of maps. Why would you be able to use containsKey on a list of maps? A list of maps doesn't have a key.Quadroon
@JBNizet Whoops!!! Thanks a lot! It is a list of maps! I didn't catch it.Slipshod
S
18

AssertJ has entry() method. You can assert map value like this.

assertThat(list)
    .extracting("myMap")
    .contains(entry("foo1", "bar1"), entry("foo2", "bar2"));

Here's javadoc : http://joel-costigliola.github.io/assertj/core/api/org/assertj/core/data/MapEntry.html

Sinh answered 27/2, 2019 at 7:19 Comment(0)
S
8

The simplest way to assert the contents of your map is chaining the extracting method:

    MyObj o1 = new MyObj();
    o1.getMyMap().put("foo", "Hello");
    o1.getMyMap().put("bar", "Bye");
    MyObj o2 = new MyObj();
    o2.getMyMap().put("foo", "Hola");
    o2.getMyMap().put("bar", "Adios");

    List<MyObj> myObjs = Arrays.asList(o1, o2);
    assertThat(myObjs).extracting("myMap").extracting("foo").contains("Hello", "Hola");
    assertThat(myObjs).extracting("myMap").extracting("bar").contains("Bye", "Adios");
Swallow answered 11/8, 2015 at 12:15 Comment(0)
C
5

If you want to use the containsKey method, you must know the type of the key at compile time (that is, you can't rely on generics). Supposing myMap is a Map<String, Long> you could do:

assertThat(list)
  .extracting("myMap")
  .asInstanceOf(InstanceOfAssertFactories.map(String.class, Long.class))
  .containsKey("key");
Colleencollege answered 3/8, 2021 at 15:11 Comment(0)
D
3

Extracting feature is documented here: http://joel-costigliola.github.io/assertj/assertj-core-features-highlight.html#extracted-properties-assertion

You have executable examples in assertj-examples, and specifically in IterableAssertionsExamples.

Hope it helps !

Deficit answered 25/7, 2015 at 11:50 Comment(0)
R
0

It's a little bit more complicated, but definitely possible:

public class Main {
    public static void main(String[] args) {
        MyObject<String, Integer> myObject1 = new MyObject<>("A", 1);
        MyObject<String, Integer> myObject2 = new MyObject<>("B", 2);
        MyObject<String, Integer> myObject3 = new MyObject<>("C", 3);

        List<MyObject<String, Integer>> myObjects = Arrays.asList(myObject1, myObject2, myObject3);

        assertThat(myObjects).extracting("myMap", Map.class).is(containingKey("A"), atIndex(0))
                                                            .is(containingKey("B"), atIndex(1))
                                                            .is(containingKey("C"), atIndex(2));
    }

    private static class MapContainsKeyCondition<K> extends Condition<Map> {
        private final K keyToContain;

        public MapContainsKeyCondition(K key) {
            this.keyToContain = key;
        }

        @Override
        public boolean matches(Map map) {
            return map.containsKey(keyToContain);
        }
    }

    private static <K> Condition<Map> containingKey(K key) {
        return new MapContainsKeyCondition<>(key);
    }

    public static class MyObject<K, V> {
        final Map<K, V> myMap;

        public MyObject(K key, V value) {
            this.myMap = Collections.singletonMap(key, value);
        }
    }
}
Rebbeccarebe answered 25/7, 2015 at 11:59 Comment(0)
S
0

One way is to extract Map from List and validate it's content as suggested here - Assertj Core Features, as follows:

@Test
public void getMyObjList() {
    assertThat(list).isNotEmpty().extracting("myMap")
            .isNotEmpty().contains(geMap());
}

private Map<String, Integer> geMap() {
    final Map<String, Integer> map = new HashMap<>();
    map.put("A", 1);
    map.put("B", 2);
    return map;
}
Surakarta answered 18/3, 2017 at 15:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.