如何自动(通过UT)检测REST合同中缺少的无参数构造函数?

时间:2019-04-03 08:31:03

标签: java rest unit-testing spring-boot

我正在开发一个SpringBoot应用程序,该应用程序包含具有许多方法的数十个REST端点。所有这些都使用@RestController注释声明。因此,大量的POJO充当了所有这些方法的合同。新开发人员常常忘记在这些类上不声明任何参数构造函数。因此,这会遇到此链接下描述的问题: https://javarevisited.blogspot.com/2014/01/why-default-or-no-argument-constructor-java-class.html

更糟糕的是,在将应用程序部署到TEST环境后会检测到此类错误。

所以我的问题是有一种简单的方法来自动检测Java中缺少的无参数构造函数吗?没有带有@EnableMvc批注的测试套件?最好最好是对新创建的POJO进行检测。

4 个答案:

答案 0 :(得分:1)

只有我知道的解决方案是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 :(得分:1)

可能有很多方法, 例如:具有自定义规则,IDE检查插件或内置代码分析的声纳。

但是我建议您编写Spring MockMVC测试(非常容易实现),有很多文章可以在线参考。 例如: https://howtodoinjava.com/spring-boot2/spring-boot-mockmvc-example/

如果Spring无法实例化代码流中的任何类或(控制器),则测试将失败。另一个好处是,您可以通过良好的质量测试来测试所有REST API(模拟所有DAO并尝试仅测试spring MVC层)。

答案 2 :(得分:1)

我将按照此处所述使用嘲讽编写单元测试:https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-testing-spring-boot-applications-testing-with-mock-environment

此外,我更喜欢使用默认构造函数而不是(无参数构造函数+ setter)进行反序列化。

答案 3 :(得分:-1)

可能是一个愚蠢的解决方案,但为什么不通过

创建一个实例
POJOClass pojoClass = new POJOClass();

断言它不是null吗?