2013-11-14 8 views
5

私は、Mavenのsrc/main/javaディレクトリに適用されるいくつかのAspectJポリシー実施側面を持っています。最近では、これらの側面のいくつかの穴が発見されているので、私は単体テストを作りたいと思います。ユニットテストAspectJのポリシー施行の側面にスマートな方法がありますか?

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

何かが完璧になる:

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

誰でも似た何かを行っていますか?いつものように

+0

Windowsの場合、ajcはバッチファイルです。そのコマンドラインを見て実行してください。あなたが必要とするのはクラスパス上のajtools.jarだと思いますが、私はメインクラスの名前を忘れてしまいます。 – aepurniet

+0

オプションはありません。誰かがajcをローカルにインストールする必要なく、さまざまなプラットフォーム上の多くの異なるマシン上でテストを実行する必要があります –

+0

aspectjコンパイラなしでSomeAspect.ajをコンパイルする方法は? – aepurniet

答えて

4

、ここに私自身の答えです:

私は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"))); 
    } 
} 

次のステップで、私はこれを拡張して特定のエラーメッセージを確認することができますが、これは最初に行います。

1

私は、Mocksを使って各アスペクトを分離し、ポイントカットマッチングを検証するためのフレームワークを書いた。これは、実際の方法や架空のメソッドの呼び出しと実行で動作します。

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

https://github.com/mock4aj/mock4aj

+0

ニース!それをチェックします! –

関連する問題