Sara
Sara

Reputation: 2515

Unit testing a class with private environment variables

I have an EJB which I want to unit test its public methods. I am testing EJB as a pojo. So I just have instantiate it and called the public method.

The problem is that public method sets some glassfish environment properties the environment variable is private. So I am not able to set it outside of the class and when I just call that public method for the environment object it throws nullPointerException.

The class that I want to test has,

@Resource(name="NameServiceEnvironment")
private Properties nameServiceEnvironment;



    public void setup() {

        // Set the environment.
        Properties environment = new Properties(); 
        environment.setProperty("name.host", this.nameServiceEnvironment.getProperty(NAME_HOST));
        environment.setProperty("name.port", this.nameServiceEnvironment.getProperty(NAME_PORT));

...}

So now for nameServiceEnvironment it throws the null pointer exception.

Now from the test class I've just instantiated the above class and called the setup method.

Thanks.

Upvotes: 1

Views: 2537

Answers (4)

Liggy
Liggy

Reputation: 1201

Add a setter for nameServiceEnvironment and inject your own nameServiceEnvironment when unit testing.

Update based on comment

or, you could extract the properties bit from setup into another method and override it in your test to fake out.

public void setup() { 
    setupEnvironment();            
    ...
}

void setupEnvironment(){ //you would override this in your unit test
   Properties environment = new Properties(); 
   environment.setProperty("name.host", this.nameServiceEnvironment.getProperty(NAME_HOST));
   environment.setProperty("name.port", this.nameServiceEnvironment.getProperty(NAME_PORT));
}

Well, not exactly a fake. You simply bypass this bit in your test.

Upvotes: 2

Alper Akture
Alper Akture

Reputation: 2465

Is it because nameServiceEnvironment is not injected? This was one of the reasons Arquillian became popular. I used it for several months to unit test ejb's in a container, but it was not easy to use (for me at least). Using arquillian, you can have all the dependency injection done, and then the test methods executed. I've also used reflection as another suggested. And depending on what DI framework you use, you can probably configure it for a test to inject that as well.

reflection code if you want to do that:

public class ATest {

@Test
public void testEjb() throws Exception {
    MyEJB myEjb = new MyEJB();
    Class<? extends MyEJB> cls = myEjb.getClass();
    Field field = cls.getDeclaredField("props");
    field.setAccessible(true);
    field.set(myEjb, new Properties());
    myEjb.somePublicMethod();
}   
class MyEJB {
    private Properties props;
    public void somePublicMethod() {
        System.out.println("props has: " + props);
    }
}

}

Upvotes: 1

MattR
MattR

Reputation: 7048

Your nameServiceEnvironment is set using

@Resource(name="NameServiceEnvironment")

so you just need to make sure your test environment has that resource configured (as it does in your Glassfish environment). You could use Spring for example.

Upvotes: 1

duffymo
duffymo

Reputation: 309028

You always have access, even to private methods. Use reflection in your test to gain access to the private properties - set them and get on with it.

Upvotes: 2

Related Questions