這是我們最終使用的技術。
因爲腳本會繼續運行,所以我們不能忽略對System.exit()
的調用。相反,我們想用所需的狀態碼拋出一個異常。我們拋出一個(自定義)ProgramExitException
時System.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])
謝謝。我清理了我們的'System.metaClass.static.invokeMethod'工作,而且看起來不那麼黑客。 – Patrick 2012-02-18 00:32:51