Единичное тестирование класса с переменными частной среды

У меня есть EJB, который я хочу, чтобы unit test его общедоступные методы. Я тестирую EJB как pojo. Поэтому я просто создал экземпляр и вызвал публичный метод.

Проблема заключается в том, что публичный метод устанавливает некоторые свойства среды Glassfish, переменная среды является частной. Поэтому я не могу установить его вне класса, и когда я просто вызываю этот открытый метод для объекта среды, он выдает исключение nullPointerException.

Класс, который я хочу проверить,

@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));

...}

Итак, теперь для nameServiceEnvironment он выбрасывает исключение нулевого указателя.

Теперь из тестового класса я только что создал экземпляр класса и назвал метод установки.

Спасибо.

Ответы

Ответ 1

У вас всегда есть доступ даже к приватным методам. Используйте отражение в своем тесте, чтобы получить доступ к частным свойствам - установите их и продолжите с ним.

Ответ 2

Добавьте установщик для nameServiceEnvironment и добавьте свой собственный nameServiceEnvironment при модульном тестировании.

Обновление на основе комментария

или вы можете извлечь бит свойств из настройки в другой метод и переопределить его в своем тесте для подделки.

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));
}

Ну, не совсем подделка. Вы просто обходите этот бит в своем тесте.

Ответ 3

Ваше имяServiceEnvironment устанавливается с помощью

@Resource(name="NameServiceEnvironment")

поэтому вам просто нужно убедиться, что ваша тестовая среда настроена таким образом (как в вашей среде Glassfish). Например, вы можете использовать Spring.

Ответ 4

Это потому, что nameServiceEnvironment не вводится? Это была одна из причин, по которой Аркиллиан стал популярным. Я использовал его в течение нескольких месяцев до unit test ejb в контейнере, но это было непросто использовать (по крайней мере для меня). Используя arquillian, вы можете выполнить всю инъекцию зависимостей, а затем выполнить тестовые методы. Я также использовал размышления, как это было предложено. И в зависимости от того, какую инфраструктуру DI вы используете, вы, вероятно, можете настроить ее для теста, чтобы ввести это также.

код отражения, если вы хотите сделать это:

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);
    }
}

}