@Test
public void testGetRecursiveDMNTypes() {

    // tAddress contains tCountry which contains tPeople which contains tAddress:
    // tPeople[structure]
    //    address[tAddress]
    // tAddress[structure]
    //     country[tCountry]
    // tCountry[structure]
    //     president[tPeople]
    final JSITItemDefinition tPeople = mock(JSITItemDefinition.class);
    final JSITItemDefinition tAddress = mock(JSITItemDefinition.class);
    final JSITItemDefinition tCountry = mock(JSITItemDefinition.class);
    final String tPeopleType = "tPeopleType";
    final String tAddressType = "tAddressType";
    final String tCountryType = "tCountryType";
    final String addressFieldName = "address";
    final String countryFieldName = "president";
    final String peopleFieldName = "people";
    when(tPeople.getName()).thenReturn(tPeopleType);
    when(tAddress.getName()).thenReturn(tAddressType);
    when(tCountry.getName()).thenReturn(tCountryType);
    final JSITItemDefinition address = mock(JSITItemDefinition.class);
    when(address.getTypeRef()).thenReturn(tAddressType);
    when(address.getName()).thenReturn(addressFieldName);
    final List<JSITItemDefinition> tPeopleFields = Arrays.asList(address);
    final JSITItemDefinition country = mock(JSITItemDefinition.class);
    when(country.getName()).thenReturn(countryFieldName);
    when(country.getTypeRef()).thenReturn(tCountryType);
    final List<JSITItemDefinition> tAddressFields = Arrays.asList(country);
    final JSITItemDefinition people = mock(JSITItemDefinition.class);
    when(people.getTypeRef()).thenReturn(tPeopleType);
    when(people.getName()).thenReturn(peopleFieldName);
    final List<JSITItemDefinition> tCountryFields = Arrays.asList(people);
    when(tPeople.getItemComponent()).thenReturn(tPeopleFields);
    when(tAddress.getItemComponent()).thenReturn(tAddressFields);
    when(tCountry.getItemComponent()).thenReturn(tCountryFields);
    final List<JSITItemDefinition> definitions = Arrays.asList(tPeople, tAddress, tCountry);
    final Map<String, ClientDMNType> dmnTypesMap = abstractKogitoDMNServiceSpy.getDMNDataTypesMap(definitions, "namespace");
    assertTrue(dmnTypesMap.containsKey(tPeopleType));
    assertTrue(dmnTypesMap.containsKey(tAddressType));
    assertTrue(dmnTypesMap.containsKey(tCountryType));
    final ClientDMNType dmnPeopleType = dmnTypesMap.get(tPeopleType);
    final ClientDMNType dmnAddressType = dmnTypesMap.get(tAddressType);
    final ClientDMNType dmnCountryType = dmnTypesMap.get(tCountryType);
    assertEquals(1, dmnPeopleType.getFields().size());
    assertTrue(dmnPeopleType.getFields().containsKey(addressFieldName));
    assertEquals(dmnAddressType, dmnPeopleType.getFields().get(addressFieldName));
    assertFalse(dmnPeopleType.isCollection());
    assertTrue(dmnPeopleType.isComposite());
    assertEquals(1, dmnAddressType.getFields().size());
    assertTrue(dmnAddressType.getFields().containsKey(countryFieldName));
    assertEquals(dmnCountryType, dmnAddressType.getFields().get(countryFieldName));
    assertFalse(dmnAddressType.isCollection());
    assertTrue(dmnAddressType.isComposite());
    assertEquals(1, dmnCountryType.getFields().size());
    assertTrue(dmnCountryType.getFields().containsKey(peopleFieldName));
    assertEquals(dmnPeopleType, dmnCountryType.getFields().get(peopleFieldName));
    assertFalse(dmnCountryType.isCollection());
    assertTrue(dmnCountryType.isComposite());
    // It must contains all elements defined in BuiltInType ENUM
    assertTrue(dmnTypesMap.size() == 17);
    for (BuiltInType builtInType : BuiltInType.values()) {
        Arrays.stream(builtInType.getNames()).forEach(name -> assertNotNull(dmnTypesMap.get(name)));
    }
}