简体   繁体   中英

how to use assertj extracting map property

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?

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

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");

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 !

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");

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);
        }
    }
}

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM