6

Maven src/main/java ディレクトリに適用されるいくつかの AspectJ ポリシー適用の側面があります。最近、これらの側面のいくつかの穴が発見されたので、それらの単体テストを作成したいと思います。

私がやりたいのは、テスト ディレクトリ (AspectJ によってコンパイルされていない) に Java ファイルを作成し、選択したファイルに対してプログラムで AspectJ コンパイラを呼び出し、結果に基づいてアサーションを作成することです。

このようなものは完璧です:

assertThat("MyJavaClass.java", producesCompilerErrorFor("SomeAspect.aj"));

誰かが似たようなことをしましたか?

4

2 に答える 2

5

いつものように、ここに私自身の答えがあります:

というクラスを作りましたAbstractAspectJPolicyEnforcementTest。一部のコンテンツは専有情報ですが、最も重要なものを紹介します。

protected Matcher<File> producesCompilationErrorWith(final File aspectFile) {
    return new AspectJCompilationMatcher(aspectFile, Result.ERROR);
}

private class AspectJCompilationMatcher extends TypeSafeMatcher<File> {
    private final File aspectFile;
    private final Result expectedResult;
    private Result result;

    public AspectJCompilationMatcher(final File aspectFile, final Result expectedResult) {
        this.aspectFile = aspectFile;
        this.expectedResult = expectedResult;
    }

    @Override
    protected boolean matchesSafely(final File javaSourceFile) {
        result = compile(javaSourceFile, aspectFile);
        return result == expectedResult;
    }

    @Override
    public void describeTo(final Description description) {
        description.appendText("compilation result: ").appendValue(result);
    }
}

enum Result {
    ERROR,
    WARNING,
    SUCCESS
}

private Result compile(final File javaFileName, final File aspectFile) {

    assertExists(javaFileName);
    assertExists(aspectFile);

    List<String> argList = newArrayList();

    // java 7 compatibility
    argList.add("-source");
    argList.add("1.7");
    argList.add("-target");
    argList.add("1.7");

    // set class path
    argList.add("-cp");
    argList.add(System.getProperty("java.class.path"));

    // add java file
    argList.add(javaFileName.getAbsolutePath());

    // add aspect files
    argList.add(aspectFile.getAbsolutePath());
    for (File additionalAspectFile : requiredAspects) {
        assertExists(additionalAspectFile);
        argList.add(additionalAspectFile.getAbsolutePath());
    }

    String[] args = argList.toArray(new String[argList.size()]);
    List<String> fails = newArrayList();
    List<String> errors = newArrayList();
    List<String> warnings = newArrayList();
    List<String> infos = newArrayList();

    // org.aspectj.tools.ajc.Main;
    Main.bareMain(args, false, fails, errors, warnings, infos);
    if (!fails.isEmpty() || !errors.isEmpty()) {
        return Result.ERROR;
    } else if (!warnings.isEmpty()) {
        return Result.WARNING;
    } else {
        return Result.SUCCESS;
    }
}

そして、テストクラスでそれを使用する方法は次のとおりです。

public class ForbiddenPackageNameAspectTest extends AbstractAspectJPolicyEnforcementTest {
    @Test
    public void testBadPackageName() throws Exception {
        assertThat(sourceFile(BadJavaClass.class),
            producesCompilationErrorWith(findAspect("ForbiddenPackageNameAspect")));
    }

    @Test
    public void testGoodPackageName() throws Exception {
        assertThat(sourceFile(ForbiddenPackageNameAspectTest.class),
                compilesWithoutWarningWith(findAspect("ForbiddenPackageNameAspect")));
    }
}

もちろん、次のステップでこれを拡張して、特定のエラー メッセージをチェックできるようにすることもできますが、最初はこれで十分です。

于 2013-11-14T16:58:06.317 に答える
2

モックを使用して各側面を分離し、ポイントカットの一致を検証するためのフレームワークを作成しました。実際のまたは架空のメソッド呼び出しと実行で動作します。

多分それはあなたを助けるかもしれません。

https://github.com/mock4aj/mock4aj

于 2014-02-06T16:43:21.753 に答える