Assertj-core: Map of list of maps not digging into list with flatExtracting/ first().extract()

Created on 7 Nov 2019  路  4Comments  路  Source: assertj/assertj-core

Summary

I have a map of lists of maps (Map<String, List<Map<String, Object>>> example below haha) and when i try to extract with flatExtracting or first().extract, it keeps trying to operate on the list directly instead of the maps inside the list.

Example

data.toString() => {links=[{id=dc63d5bf-7eda-45c1-995f-c33de2cc2dbd, name=Financing Plan}]}

// regenerating the data here just for the sake of example
Map<String, Object> linkSubType = ImmutableMap.of(
        "id", "dc63d5bf-7eda-45c1-995f-c33de2cc2dbd",
        "name", "Financial Plan"
);
List<Map<String, Object>> linkSubTypes = Lists.newArrayList(linkSubType);
Map<String, Object> data = ImmutableMap.of(
        "linkSubTypes", linkSubTypes
);

assertThat(data).extracting("linkSubTypes").flatExtracting("id", "name").containsOnly(
    tuple("dc63d5bf-7eda-45c1-995f-c33de2cc2dbd", "Financing Plan")
)

error:

org.assertj.core.util.introspection.IntrospectionError: 
Can't find any field or property with name 'id'.
Error when introspecting properties was :
- No getter for property 'id' in java.util.ArrayList 
Error when introspecting fields was :
- Unable to obtain the value of the field <'id'> from <[{id=dc63d5bf-7eda-45c1-995f-c33de2cc2dbd, name=Financing Plan}]>

and if i run

assertThat(data).extracting("linkSubTypes").first().extracting("id", "name").isEqualTo(
    tuple("dc63d5bf-7eda-45c1-995f-c33de2cc2dbd", "Financing Plan")
);

i get the same error

org.assertj.core.util.introspection.IntrospectionError: 
Can't find any field or property with name 'id'.
Error when introspecting properties was :
- No getter for property 'id' in java.util.ArrayList 
Error when introspecting fields was :
- Unable to obtain the value of the field <'id'> from <[{id=dc63d5bf-7eda-45c1-995f-c33de2cc2dbd, name=Financing Plan}]>

Any help would be greatly appreciated, or let me know if you need more code/better example.

Most helpful comment

The problem comes from the fact extracting can't choose the right assertion
type from the Map values type and thus you call extracting on the ObjectAssert
which is unable to find Map entries in a List.
To achieve what you want, you need to provide extracting an assertFactory as follow:

assertThat(data)
  .extracting("linkSubTypes", as(InstanceOfAssertFactories.LIST))
  .extracting("id", "name")
  .containsOnly(tuple("dc63d5bf-7eda-45c1-995f-c33de2cc2dbd", "Financing Plan"));

Note that flatExtracting let you match properties into a list and extracting requires to match tuples.

assertThat(data)
  .extracting("linkSubTypes", as(InstanceOfAssertFactories.LIST))
  .flatExtracting("id", "name")
  .containsOnly("dc63d5bf-7eda-45c1-995f-c33de2cc2dbd", "Financing Plan");

All 4 comments

馃憖

The problem comes from the fact extracting can't choose the right assertion
type from the Map values type and thus you call extracting on the ObjectAssert
which is unable to find Map entries in a List.
To achieve what you want, you need to provide extracting an assertFactory as follow:

assertThat(data)
  .extracting("linkSubTypes", as(InstanceOfAssertFactories.LIST))
  .extracting("id", "name")
  .containsOnly(tuple("dc63d5bf-7eda-45c1-995f-c33de2cc2dbd", "Financing Plan"));

Note that flatExtracting let you match properties into a list and extracting requires to match tuples.

assertThat(data)
  .extracting("linkSubTypes", as(InstanceOfAssertFactories.LIST))
  .flatExtracting("id", "name")
  .containsOnly("dc63d5bf-7eda-45c1-995f-c33de2cc2dbd", "Financing Plan");

thanks @mbaechler, does that address your issue @jmondo?

yes it does! thanks everyone!

Was this page helpful?
0 / 5 - 0 ratings