Question

I am trying to write unit test for my below old legacy enum class. The method which I am trying to unit test is - toLocalPookString.

Whenever I am running my unit test code, it is always going inside the if statement in toLocalPookString method since this is always getting resolved to CORP.

public enum DatacenterEnum {
    CORP, PHX, SLC, LVS;

    private static final DatacenterEnum ourlocation = compareLocation();

    private static DatacenterEnum compareLocation() {
        // some code here
    }

    private String toLocalPookString() {
        if (this == CORP || !(TestUtils.getEnvironmentName().equalsIgnoreCase("production"))) {
            return "/pp/dc/phx";
        }

        return "/pp/dc/" + name().toLowerCase();
    }


    public static final String BETA_POOK_STRING = ourlocation.toLocalPookString();

}

Is there any way I can mock this to PHX or SLC or LVS apart from CORP so that in toLocalPookString it should not go inside if statement? I am using jmockit here.

new MockUp<TestUtils>() {
    @Mock
    public String getEnvironmentName() {
    return "production";
    }
};

String ss = DatacenterEnum.BETA_POOK_STRING;
System.out.println(ss);

It is pretty simple but somehow I am not able to understand how to do it? Any thoughts?

Was it helpful?

Solution

Well, you could easily mock the enum, as follows:

new MockUp<DatacenterEnum>() {
    @Mock DatacenterEnum compareLocation() { return DatacenterEnum.LVS; }
};

However, because the JVM can only perform static initialization once for a given class/enum, the test would only work if the enum hadn't yet been loaded and initialized. So, a more robust test would be the following.

@Test
public void whenDatacenterIsNotCORPThenLocalPookStringShouldIncludeEnumName() {
    new MockUp<TestUtils>() {
        @Mock String getEnvironmentName() { return "production"; }
    };

    DatacenterEnum notCORP = DatacenterEnum.LVS;
    String ss = Deencapsulation.invoke(notCORP, "toLocalPookString");

    assertTrue(ss.toUpperCase().endsWith(notCORP.name()));
}

This works, but note that writing separate tests for private methods is generally considered bad form. Ideally, tests should call public methods which would indirectly exercise the private ones. In this particular case, however, there is no such public method, so I guess it's acceptable.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top