Jurn
Jurn

Reputation: 1088

Mock an injection in an enum

For a framework I am trying to inject another class in my enum to provide some environment information. It appears to work however I do not know how to test this in a unit test. Please help..

Enum:

public enum BestemmingBad implements Bestemming {

 TEST("test"),
 TEST2("test2");

 BestemmingBad(final String value) {
        this.value = value;
    }

    @Override
    public String getUrl() {
        final String jmsServer = Guice.createInjector().getInstance(MyEnvironmentConfig.class).retrieveJmsServerName();
        return jmsServer + "/" + value;
    }
}

My test;

public class BestemmingenTest extends ExtendedEasyMockSupport {

private Environment environmentMock;

@Before
public void setUp() {
    environmentMock = createMock(Environment.class);
}

@Test
public void BestemmingBadTb5Test() throws UnknownHostException {
     expect(environmentMock.getComputerName()).andReturn("TB5");
     replayAll();

     final BestemmingBad bestemming = BestemmingBad.TEST;
     assertThat(bestemming.getUrl(), is("jms@testserver@jms1/test"));
}

private class TestModule extends TestGuiceModule {

    @Provides
    public Environment provideEnvironment() {
        return environmentMock;
    }
}

Upvotes: 1

Views: 1415

Answers (1)

Olivier Grégoire
Olivier Grégoire

Reputation: 35417

You shouldn't "inject" into an enum

Instead use a good old switch statement, or move your injection point into something really injectable like a class.

Why are you injecting an enum? It makes no sense. An enum is entirely static. You shouldn't add behavior to an enum unless is extremely basic and consistent. What you're doing here is neither. Also, calling your method will be very slow because Guice will have to initialize the Injector at every single call, which is definitely not what you want.

What you should do instead is moving the business logic outside of the enum itself:

public enum BestemmingBad implements Bestemming {
  TEST("test"), TEST2("test2");
  private final String value;
  BestemmingBad(String value) { this.value = value; }
  public String getValue() { return value; }
}

public class UrlGetter {
  private String jmsServer;
  @Inject UrlGetter(MyEnvironmentConfig config) {
    jmsServer = config.retrieveJsmServerName();
  }
  public String getUrl(Bestemming bestemming) { // or BestemmingBad
    return jmsServer + "/" + bestemming.getValue();
  }
}

Then your test doesn't require anything complicated: just test UrlGetter.getUrl(Bestemming) very basically.

Upvotes: 3

Related Questions