最終的に使用した技術は次のとおりです。
System.exit()
の呼び出しを無視することはできません。スクリプトは引き続き実行されるためです。代わりに、目的のステータスコードで例外をスローする必要があります。私たちは、System.exit()
が我々のテスト
class ProgramExitException extends RuntimeException {
int statusCode
public ProgramExitException(int statusCode) {
super("Exited with " + statusCode)
this.statusCode = statusCode
}
}
に呼び出されたとき、我々は
/**
* 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)
}
}
この例外をスローするSystem.exit()
を傍受し、最後に私たちはGroovyShell
キャッチに何かProgramExitException
を持ってからステータスコードを返します(カスタム)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