Гашение полей с помощью Reflection - PullRequest
1 голос
/ 20 января 2010

Я пишу тестовый фреймворк Junit для тестирования веб-сервисов.

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

Для этого у меня есть конструкторы, которые по-разному принимают разные входные данные; пока все просто.

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

Вместо того, чтобы засорять (в некоторых случаях очень длинные) тесты с помощью операторов if, решающих, устанавливать или не устанавливать значение, я написал аннотацию @ Необязательно.

Добавление этой аннотации приводит к ее обнулению с помощью следующего кода:

     /**
     * Find all of the fields annotated with optional and null them
     * @throws IllegalAccessException 
     * @throws IllegalArgumentException 
     */
    private void blankOptionalFields() throws IllegalAccessException{

        for(Field field: this.getClass().getDeclaredFields()){


            Annotation optionalAnnotation = field.getAnnotation(Optional.class);

            if(!(field.isSynthetic()) && optionalAnnotation instanceof Optional){

                field.setAccessible(true);
                try{
                    field.set(this, null);
                }
                catch(IllegalArgumentException e){
                    logger.debug("Tried to set a scalar field to null!", e);
                }
            }
        }
    }

Итак, две вещи:

1: Несмотря на то, что это работает, оно почему-то кажется хрупким / опасным, должен ли быть лучший подход? 2: Если это не простой подход, каков наилучший способ настройки скалярных значений для сопоставления значений?

Ответы [ 3 ]

1 голос
/ 20 января 2010

Как насчет определения интерфейса, содержащего только один метод, который исключает необязательные атрибуты? Вы можете протестировать объект для реализации интерфейса и вызвать метод напрямую.

Это обрабатывает определенные исключения более элегантно, чем попытка создать ситуацию с использованием всех отражений с помощью отражения:

interface Blankable {

    /** @return true if all optional fields are successfully blanked. **/
    public boolean blankOptionalFields();
}

и используйте как:

if (obj implements Blankable) {

    if (!((Blankable) obj).blankOptionalFields()) {

        logger.debug("Could not blank optional fields for " + obj);
    }
}
0 голосов
/ 20 января 2010

Я не очарован этим подходом, потому что вы смешиваете тестовый код с вашим рабочим кодом.

Если вы знаете, какие поля являются обязательными заблаговременно, возможно ли просто зациклить эти поля при установке их без сложной структуры if?

0 голосов
/ 20 января 2010

Я бы реорганизовал тесты, отделив код инициализации от фактического кода теста.В этом отношении вы можете поместить фактический тестовый код (код, который вызывает веб-сервис) в метод, который используется несколькими методами тестирования.

В качестве полуотносительного комментария: я бы подумал о «единице«тесты как самостоятельные методы обслуживания, а« интеграционные »тесты - как веб-сервис.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...