Как автоматически (по UT) обнаружить отсутствующие конструкторы без аргументов в контрактах REST? - PullRequest
0 голосов
/ 03 апреля 2019

Я работаю над приложением SpringBoot, которое содержит десятки конечных точек REST с десятками методов. Все они объявлены с использованием аннотации @RestController. Следовательно, появляется большое количество POJO, которые служат контрактами для всех этих методов. И часто случается, что новые разработчики забывают объявлять конструкторы без аргументов в этих классах. Так что это сталкивается с проблемами, описанными по этой ссылке: https://javarevisited.blogspot.com/2014/01/why-default-or-no-argument-constructor-java-class.html

И что еще хуже, ошибки такого рода обнаруживаются после развертывания приложения в среде TEST.

Итак, мой вопрос: есть ли простой способ автоматически обнаруживать отсутствующие конструкторы без аргументов в Java? Без тестового набора с аннотацией @EnableMvc? Предпочтительно было бы лучше всего обнаружить такие случаи для вновь созданных POJO.

Ответы [ 4 ]

2 голосов
/ 03 апреля 2019

Единственное известное мне решение - это java Reflection, вам нужно будет отсканировать пакет, затем проверить аннотацию, а затем конструктор по умолчанию, попробовать этот тестовый класс, который будет печатать классы без конструктора по умолчанию.

public class TestListIni {


    String scaningPackage = "your package name";

    public void startTesting() {

        List<ClassLoader> classLoadersList = new LinkedList<ClassLoader>();
        classLoadersList.add(ClasspathHelper.contextClassLoader());
        classLoadersList.add(ClasspathHelper.staticClassLoader());

        Reflections reflections = new Reflections(
                new ConfigurationBuilder().setScanners(new SubTypesScanner(false), new ResourcesScanner())
                        .setUrls(ClasspathHelper.forClassLoader(classLoadersList.toArray(new ClassLoader[0])))
                        .filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix(scaningPackage))));

        Set<Class<? extends Object>> allClasses = reflections.getSubTypesOf(Object.class);

        allClasses.forEach(oneClass -> {
            RestController addTotest = oneClass.getAnnotation(RestController.class);
            if (addTotest != null) {
                //check for default constructor
                boolean flag = hasParameterlessPublicConstructor(oneClass);
                if(!flag){
                    sysout("this has no default constructor " oneClass.getName());
                }
            } else {
                System.err.println("Scanned and exclued class " + oneClass.getName());
            }
        });


    }

    private boolean hasParameterlessPublicConstructor(Class<?> clazz) {
    for (Constructor<?> constructor : clazz.getConstructors()) {

        if (constructor.getParameterCount() == 0) { 
            return true;
        }
    }
    return false;
    }
}

зависимость:

<dependency>
        <groupId>org.reflections</groupId>
        <artifactId>reflections</artifactId>
        <version>0.9.11</version>
</dependency>
1 голос
/ 03 апреля 2019

Я бы написал модульное тестирование с помощью mockMvc, как описано здесь: https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-testing-spring-boot-applications-testing-with-mock-environment

Более того, я предпочитаю использовать конструктор по умолчанию вместо (конструктор без аргументов + установщик) для десериализации.

1 голос
/ 03 апреля 2019

Там может быть много способов, например: Sonar с пользовательскими правилами, плагинами проверки IDE или встроенным анализом кода.

Но я рекомендую вам написать весенние тесты MockMVC (очень простые в реализации), есть многостатей, которые вы можете ссылаться в Интернете.Например: https://howtodoinjava.com/spring-boot2/spring-boot-mockmvc-example/

Если Spring не может создать экземпляр какого-либо класса или (контроллера) в потоке кода, ваш тест не пройден.Другое преимущество заключается в том, что вы можете протестировать все свои REST API с помощью качественного теста (смоделируйте все DAO и попробуйте протестировать только пружинный MVC-слой).

0 голосов
/ 03 апреля 2019

Может быть, это глупое решение, но почему бы просто не создать экземпляр с помощью

POJOClass pojoClass = new POJOClass();

и утверждать, что он не равен нулю?

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