2013-11-14 34 views
5

我有幾個適用於我的Maven src/main/java目錄的AspectJ策略實施方面。最近發現了這些方面的一些漏洞,所以我想爲它們創建單元測試。有沒有一種智能的方式來測試AspectJ策略執行方面的單元測試?

我想要做的是在測試目錄(不是由AspectJ編譯)中創建Java文件,然後以編程方式在所選文件上調用AspectJ編譯器並基於結果進行斷言。

像這樣的事情將是完美的:

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

,有沒有人做過類似的事情?

+0

如果你在windows上,ajc是一個批處理文件。只需查看該命令行並執行即可。認爲你需要的只是classpath上的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

好!將檢查出來! –

相關問題