Home > Enterprise >  Apache Commons StringSubstitutor Working in main Method Call but failing when Run As Part of a Unit
Apache Commons StringSubstitutor Working in main Method Call but failing when Run As Part of a Unit

Time:12-22

So I am trying to create a method that replaces Placeholders in a block of text read from a file. I have created a method that utilises StringSubstitutor from Apache Commons Text, and when I call my method in the main method, it works, yet my Unit Test fails.

The replacePlaceholders method:

public StringBuilder replacePlaceholdersInText(Person person) {
        PersonPlaceholders placeholders = new PersonPlaceholders();
        StringBuilder text = READER.readDoc();
        Map<String, String> toReplace = placeholders.getPlaceholders(person);
        StringSubstitutor sub = new StringSubstitutor(toReplace);
        text = new StringBuilder(sub.replace(text));
        LOGGER.info(text);
        return text;
    }

PersonPlaceholders Class:

public class PersonPlaceholders implements Placeholders<Person, String, String> {
    @Override
    public Map<String, String> getPlaceholders(Person person) {
        Map<String, String> valueMap = new HashMap<>();
        valueMap.put("first_name", person.getFirstName());
        valueMap.put("last_name", person.getLastName());
        valueMap.put("dob", person.getDob().toString());
        return valueMap;
    }
}

My Unit Test:

@ExtendWith(MockitoExtension.class)
public class PersonToFileTest {
    @Mock
    WordDocumentReader reader;
    @InjectMocks
    PersonToFile toFile;

@Test
    public void helloJohnDoe() {
        Person person = new Person();
        person.setFirstName("John");
        person.setLastName("Doe");
        person.setDob(LocalDate.of(2000, 5, 23));
        StringBuilder text = new StringBuilder("Hello ${first_name} ${last_name}. Your date of birth is ${dob}.");
        StringBuilder expected = new StringBuilder("Hello John Doe. Your date of birth is 2000-05-23.");

        when(reader.readDoc()).thenReturn(text);

        assertEquals(expected, toFile.replacePlaceholdersInText(person));

        verify(reader).readDoc();
    }
}

The difference:

Expected :Hello John Doe. Your date of birth is 2000-05-23.
Actual   :Hello ${first_name} ${last_name}. Your date of birth is ${dob}.

Yet when I run my main method:

public static void main(String[] args) {
        PersonToFile toFile = new PersonToFile();
        toFile.replacePlaceholdersInText(new Person("John", "Doe", LocalDate.of(2000, 2, 12)));
    }

I get this result, (Text is read from a file so that's why format is slightly different):

Hi John Doe.
Your date of birth is 2000-02-12.
END OF FILE!

I've used Mockito to mock my WordDocumentReader Class, and used the debugger to verify that it is being mocked, that the mock is being interacted with.

This seems to be an issue with the StringSubstitutor.replace() method not actually being executed in the test, but I am not sure as to why. As I said, the test does everything I expect, until I get to the .replace method of the StringSubstitutor class.

CodePudding user response:

Okay so I thought creating a new StringBuilder() with the result of the StringSubstitutor.replace() might not be ideal so I changed the replacePlaceholdersInText() to this:

public StringBuilder replacePlaceholdersInText(Person person) {
        PersonPlaceholders placeholders = new PersonPlaceholders();
        StringBuilder text = READER.readDoc();
        Map<String, String> toReplace = placeholders.getPlaceholders(person);
        StringSubstitutor sub = new StringSubstitutor(toReplace);
        text.replace(0, text.length(), sub.replace(text));
        LOGGER.info(text);
        return text;
    }

And it worked.

If someone knows of a better way I am all ears, but my Unit test passes, and my main method works as expected.

  • Related