### Question:
ResolveException extends RuntimeException { @Override public String getMessage() { return rootComponentInfo() + problemInfo(); } ResolveException(DeclaringComponent current, DeclaringComponent root, String message);  ResolveException(DeclaringComponent current, DeclaringComponent root, String message, Throwable cause); @Override String getMessage();  }### Answer:
@Test void withoutCause() { ResolveException exception = new ResolveException(current, root, "Can't resolve placeholder"); assertEquals("Can't build configs for root component 'root[e]'.\n" + "Exception in\n" + "\tcurrent[e1]'\n" + "Can't resolve placeholder", exception.getMessage().trim()); exception.setProperty(p); assertEquals("Can't build configs for root component 'root[e]'.\n" + "Exception in\n" + "\tcurrent[e1]'\n" + "\tkey=value\n" + "Can't resolve placeholder", exception.getMessage().trim()); }
@Test void withCauseMessage() { ResolveException exception = new ResolveException(current, root, "Can't resolve placeholder", new NullPointerException("NPE")); assertEquals("Can't build configs for root component 'root[e]'.\n" + "Exception in\n" + "\tcurrent[e1]'\n" + "Can't resolve placeholder\n" + "Cause: NPE", exception.getMessage()); exception.setProperty(p); assertEquals("Can't build configs for root component 'root[e]'.\n" + "Exception in\n" + "\tcurrent[e1]'\n" + "\tkey=value\n" + "Can't resolve placeholder\n" + "Cause: NPE", exception.getMessage()); }