2012-02-16 166 views
15

我們有一個Groovy腳本,當的0有效時退出,non-0 status對於不同類型的故障條件。例如,如果腳本以用戶和電子郵件地址作爲參數,則對於無效的用戶,將退出status1,對於無效的電子郵件地址格式,則退出status2。我們爲此使用System.exit(statusCode)。這工作正常,但使腳本很難編寫測試用例。如何在Groovy腳本中設置退出狀態

在測試中,我們創造我們GroovyShell,創造我們Binding並調用shell.run(script,args)。對於斷言失敗條件的測試,System.exit()會導致JVM(和測試)退出。

是否有其他方法可以使用System.exit()退出Groovy腳本?我嘗試用拋出未捕獲的異常,但雜波的輸出和總是讓狀態碼1

在我們的測試情況下,我也嘗試用System.metaClass.static.invokeMethod改變System.exit()行爲不退出JVM,但似乎像一個醜陋的黑客。

回答

9

imho System.metaClass.static.invokeMethod看起來不錯。這是測試,黑客在這裏很好。

你也可以創建自己包裝它周圍,如:

class ExitUtils { 

    static boolean enabled = true 

    static exit(int code) { 
     if (!ExitUtils.enabled) { 
      return //TODO set some flag? 
     } 
     System.exit(code) 
    } 

} 

,同時禁用測試。

+0

謝謝。我清理了我們的'System.metaClass.static.invokeMethod'工作,而且看起來不那麼黑客。 – Patrick 2012-02-18 00:32:51

4

這是我們最終使用的技術。

因爲腳本會繼續運行,所以我們不能忽略對System.exit()的調用。相反,我們想用所需的狀態碼拋出一個異常。我們拋出一個(自定義)ProgramExitExceptionSystem.exit()被稱爲在我們的測試中

class ProgramExitException extends RuntimeException { 

    int statusCode 

    public ProgramExitException(int statusCode) { 
     super("Exited with " + statusCode) 
     this.statusCode = statusCode 
    } 
} 

然後我們截取System.exit()拋出該異常

/** 
* Make System.exit throw ProgramExitException to fake exiting the VM 
*/ 
System.metaClass.static.invokeMethod = { String name, args -> 
    if (name == 'exit') 
     throw new ProgramExitException(args[0]) 
    def validMethod = System.metaClass.getStaticMetaMethod(name, args) 
    if (validMethod != null) { 
     validMethod.invoke(delegate, args) 
    } 
    else { 
     return System.metaClass.invokeMissingMethod(delegate, name, args) 
    } 
} 

,最後我們有GroovyShell捕捉任何ProgramExitException,並從返回的狀態代碼run方法。

/** 
* Catch ProgramExitException exceptions to mimic exit status codes 
* without exiting the VM 
*/ 
GroovyShell.metaClass.invokeMethod = { String name, args -> 
    def validMethod = GroovyShell.metaClass.getMetaMethod(name, args) 
    if (validMethod != null) { 
     try { 
      validMethod.invoke(delegate, args) 
     } catch (ProgramExitException e) { 
      return e.statusCode 
     } 
    } 
    else { 
     return GroovyShell.metaClass.invokeMissingMethod(delegate, name, args) 
    } 
} 

我們的測試可以留在尋找簡單,我們不需要更改任何腳本,我們得到我們在命令行中運行預期的行爲。

assertEquals 'Unexpected status code', 0, shell.run(script,[arg1, arg2]) 
assertEquals 'Unexpected status code', 10, shell.run(script,[badarg1, badarg2])