Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
测试AbstractProcessor(Java在编译时的注释处理)_Java_Unit Testing_Testing_Annotations_Preprocessor - Fatal编程技术网

测试AbstractProcessor(Java在编译时的注释处理)

测试AbstractProcessor(Java在编译时的注释处理),java,unit-testing,testing,annotations,preprocessor,Java,Unit Testing,Testing,Annotations,Preprocessor,我正在写一个依赖于AbstractProcessor类的库,因为我想写一个很棒的库,所以我也想有一个很好的覆盖范围。由于预处理器在编译时工作,我不确定如何测试代码 我考虑了一些构建失败的测试场景。然而,我怎样才能测试它呢?我必须执行gradle并检查退出代码吗?是否有一种干净的方法来验证构建失败是由预期原因引起的,还是我还需要编写某种解析器?这将是一个巨大的开销只是为了一个良好的覆盖 对于需要举例说明的人: @SupportedAnnotationTypes("eu.rekisoft.java.

我正在写一个依赖于AbstractProcessor类的库,因为我想写一个很棒的库,所以我也想有一个很好的覆盖范围。由于预处理器在编译时工作,我不确定如何测试代码

我考虑了一些构建失败的测试场景。然而,我怎样才能测试它呢?我必须执行gradle并检查退出代码吗?是否有一种干净的方法来验证构建失败是由预期原因引起的,还是我还需要编写某种解析器?这将是一个巨大的开销只是为了一个良好的覆盖

对于需要举例说明的人:

@SupportedAnnotationTypes("eu.rekisoft.java.preprocessor.Decorator")
@SupportedSourceVersion(SourceVersion.RELEASE_7)
public class ExamplePreprocessor extends AbstractProcessor {

    public ExamplePreprocessor() {
        super();
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        for(Element elem : roundEnv.getElementsAnnotatedWith(Decorator.class)) {
            Method method = Method.from((ExecutableElement)elem);
            if(!method.matchesTypes(String.class, StringBuilder.class)) {
                processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "No! " + elem + " has the wrong args!");
            } else {
                processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Yey " + elem + " this is fine!");
            }
        }
        return true; // no further processing of this annotation type
    }
}
最后是无聊的注释:

@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.METHOD)
public @interface Decorator {
}

您还可以在签出项目,只需签出项目并执行gradlew cJ。您可能必须修复linux和mac上脚本缺少的x权限。

以前编写编译器和注释处理器的团队已经解决了此问题,因此您可以重新使用他们的解决方案

javac团队使用一个名为。 例如,下面是一个示例,它使用不同的命令行参数编译源文件6次,表示每个源文件的参数不同


该团队专门为注释处理器设计了一个测试框架。下面是一个使用该框架的示例,其中特别的//::注释指示注释处理器预期发出的行,或者。

谷歌有一个非常好的用于测试编译的API。下面是一个测试.java文件是否使用junit处理器编译的示例

package org.coffeebag.processor;

import com.google.testing.compile.JavaFileObjects;
import com.google.testing.compile.JavaSourceSubjectFactory;
import org.junit.Test;

import java.io.File;
import java.net.MalformedURLException;

import static org.truth0.Truth.ASSERT;

public class ExampleTest {

    @Test
    public void EmptyClassCompiles() throws MalformedURLException {
        final MyProcessor processor = MyProcessor.testMode();
        File source = new File("path/to/test/file.java");
        ASSERT.about(JavaSourceSubjectFactory.javaSource())
                .that(JavaFileObjects.forResource(source.toURI().toURL()))
                .processedWith(processor)
                .compilesWithoutError();
    }
}

我们已经编写了一个简化的API,可以帮助访问javax.tools.JavaCompiler API以进行内存中的Java编译,它允许编写简单的基于JUnit的测试。在您的示例中,您可以编写:

@Test
public void testFailAnnotationProcessing() {
    ExamplePreprocessor p = new ExamplePreprocessor();
    try {
        Reflect.compile(
            "com.example.test.FailAnnotationProcessing",
            "package com.example.test; " +
            "public class FailAnnotationProcessing { " +
            "    @com.example.Decorator " +
            "    public int breakBuild() { " +
            "        return -1; " +
            "    } " +
            "}",
            new CompileOptions().processors(p)
        ).create().get();
        Assert.fail();
    }
    catch (ReflectException expected) {}
}

@Test
public void testSucceedAnnotationProcessing() {
    ExamplePreprocessor p = new ExamplePreprocessor();
    Reflect.compile(
        "com.example.test.SucceedAnnotationProcessing",
        "package com.example.test; " +
        "public class SucceedAnnotationProcessing { " +
        "    @com.example.Decorator " +
        "    public String willCompile(StringBuilder sb) { " +
        "        return null; " +
        "    } " +
        "}",
        new CompileOptions().processors(p)
    ).create().get();
}

.

请分享您的代码和迄今为止编写的测试场景。他们怎么了?只是想知道你知道我在说什么吗?这是一个高度复杂的话题,如果你熟悉它,我的问题的抽象层次应该可以。但是,如果这让您更清楚的话,我可以添加一个示例。@RobertColumbia这里有一个简单的示例项目,无法按预期编译:您只需要签出该项目并执行gradlew cJ,如果您使用linux,您必须修复脚本缺少的x权限。我正在尝试使用该jtreg库,但我并不真正了解如何使用它。我将尝试在gradle中tun jtreg,现在我知道我可以运行java-Dprogram=jtreg-jar/tmp/jtreg/lib/jtreg.jar,但是我需要应用哪些参数?@Compile注释如何启动新的编译过程?我一点也不明白。好吧,我想我现在管理好了,但是我的引用文件不匹配。如何找到文件的确切格式?只是预期的错误输出?是的,jtreg要求编译器输出与目标文件匹配。jtreg不会尝试对输出进行巧妙的解析。关于如何运行jtreg,我建议查看jtreg文档。哦,伙计,我现在调试了CompileAction.CompareGoldConfigure。。。我没有注意到输出流中有调试消息。因此,它不只是查看错误流。很高兴知道!
@Test
public void testFailAnnotationProcessing() {
    ExamplePreprocessor p = new ExamplePreprocessor();
    try {
        Reflect.compile(
            "com.example.test.FailAnnotationProcessing",
            "package com.example.test; " +
            "public class FailAnnotationProcessing { " +
            "    @com.example.Decorator " +
            "    public int breakBuild() { " +
            "        return -1; " +
            "    } " +
            "}",
            new CompileOptions().processors(p)
        ).create().get();
        Assert.fail();
    }
    catch (ReflectException expected) {}
}

@Test
public void testSucceedAnnotationProcessing() {
    ExamplePreprocessor p = new ExamplePreprocessor();
    Reflect.compile(
        "com.example.test.SucceedAnnotationProcessing",
        "package com.example.test; " +
        "public class SucceedAnnotationProcessing { " +
        "    @com.example.Decorator " +
        "    public String willCompile(StringBuilder sb) { " +
        "        return null; " +
        "    } " +
        "}",
        new CompileOptions().processors(p)
    ).create().get();
}