### Question:
PlaceholderResolver { @VisibleForTesting public static List<Placeholder> extractPlaceholders(String value) { List<Placeholder> namesAndDefaults = new ArrayList<>(); for (String placeholder : extractPlaceholderStrings(value)) { Matcher placeholderMatcher = PLACEHOLDER_REGEX_CAPTURE_NAME_AND_DEFAULT.matcher(placeholder); if (placeholderMatcher.matches()) { namesAndDefaults.add(new Placeholder(placeholderMatcher.group(1), placeholderMatcher.group(2))); } } return namesAndDefaults; } PlaceholderResolver(ObjectNode rootNode, Map<String, String> externalProperties); static Collection<UnresolvedPlaceholder> resolvePlaceholders(JsonNode rootNode, Map<String, String> externalProperties); static Collection<UnresolvedPlaceholder> resolvePlaceholders(JsonNode rootNode, Properties properties); Collection<UnresolvedPlaceholder> resolve(); @VisibleForTesting static String replacePlaceholder(String originalString, String placeholderName, String placeholderValue); @VisibleForTesting static List<Placeholder> extractPlaceholders(String value);  }### Answer:
@Test public void extractsPlaceholderNamesAndDefaults() { String valueWithPlaceholders = "foo ${with.default:defaultValue} bar ${without.default} ${configLocation:classpath:}foo"; List<Placeholder> placeholders = PlaceholderResolver.extractPlaceholders(valueWithPlaceholders); List<Placeholder> expected = ImmutableList.of( new Placeholder("with.default", "defaultValue"), new Placeholder("without.default"), new Placeholder("configLocation", "classpath:")); assertThat(placeholders, is(expected)); }
@Test public void extractsPlaceholderNamesAndEmptyDefaults() { String valueWithPlaceholders = "${FOO:}"; List<Placeholder> placeholders = PlaceholderResolver.extractPlaceholders(valueWithPlaceholders); assertThat(placeholders, is(singletonList(new Placeholder("FOO", "")))); }