### Question:
BeanExpander extends MapExpander { @Override public String expand(ExpressionVariable variable, Object value) { Map<String, Object> beanValueMap; try { beanValueMap = new LinkedHashMap<>(this.expandBean(variable, null, value)); } catch (Exception ex) { throw new IllegalStateException("Error occurred expanding Bean " + value.getClass().getSimpleName() + ". " + ex.getMessage(), ex); } return super.expand(variable, beanValueMap); } BeanExpander(ExpanderRegistry expanderRegistry); @Override String expand(ExpressionVariable variable, Object value);  }### Answer:
@Test void simpleObject_expandLikeMap_withUndefinedValue_Missing() { Address address = new Address(); address.setStreetNumber("121B"); address.setStreetName("Baker St."); address.setTown("London"); address.setCountry("England"); address.setGivenName("Sherlock"); address.setSurname("Holmes"); ExpressionVariable expressionVariable = mock(ExpressionVariable.class); Expression expression = Expressions.create("{?address*}"); when(expressionVariable.getName()).thenReturn("address"); when(expressionVariable.getPrefix()).thenReturn(0); when(expressionVariable.getExpression()).thenReturn(expression); when(expressionVariable.isExploded()).thenReturn(true); BeanExpander expander = new BeanExpander(new CachingExpanderRegistry()); String expanded = expander.expand(expressionVariable, address); assertThat(expanded).isEqualToIgnoringCase("country=England&givenName=Sherlock&" + "streetName=Baker%20St.&streetNumber=121B&surname=Holmes" + "&town=London"); }
@Test void nestedObjects_expandWith_dotNotation() { Post post = new Post("Title", "Summary"); post.setCategory("sports"); post.addTag("hockey"); post.addTag("ice"); post.addTag("Canada"); BeanExpander expander = new BeanExpander(new CachingExpanderRegistry()); ExpressionVariable expressionVariable = mock(ExpressionVariable.class); Expression expression = Expressions.create("{?post*}"); when(expressionVariable.getName()).thenReturn("post"); when(expressionVariable.getPrefix()).thenReturn(0); when(expressionVariable.getExpression()).thenReturn(expression); when(expressionVariable.isExploded()).thenReturn(true); String expanded = expander.expand(expressionVariable, post); assertThat(expanded).isEqualToIgnoringCase( "category.label=sports&category.name=sports&summary=Summary&tags=hockey%2Cice%2CCanada&title=Title"); }
@Test void property_withoutReadMethod_isSkipped() { Post post = new Post("Title", "Summary"); post.setCategory("sports"); post.addTag("hockey"); post.addTag("ice"); post.addTag("Canada"); post.setPublished(LocalDateTime.now()); BeanExpander expander = new BeanExpander(new CachingExpanderRegistry()); ExpressionVariable expressionVariable = mock(ExpressionVariable.class); Expression expression = Expressions.create("{?post*}"); when(expressionVariable.getName()).thenReturn("post"); when(expressionVariable.getPrefix()).thenReturn(0); when(expressionVariable.getExpression()).thenReturn(expression); when(expressionVariable.isExploded()).thenReturn(true); String expanded = expander.expand(expressionVariable, post); assertThat(expanded).isEqualToIgnoringCase( "category.label=sports&category.name=sports&summary=Summary&tags=hockey%2Cice%2CCanada&title=Title"); }