2012-02-16 67 views
15

Chúng tôi có Tập lệnh Groovy thoát với status của 0 khi mọi thứ hoạt động và non-0 status cho các loại điều kiện lỗi khác nhau. Ví dụ: nếu tập lệnh lấy người dùng và địa chỉ email làm đối số, nó sẽ thoát bằng một số status của 1 cho người dùng không hợp lệ và status của 2 để định dạng địa chỉ email không hợp lệ. Chúng tôi sử dụng System.exit(statusCode) cho việc này. Điều này làm việc tốt, nhưng làm cho các kịch bản khó khăn để viết các trường hợp thử nghiệm cho.Cách đặt trạng thái thoát trong Tập lệnh Groovy

Trong thử nghiệm, chúng tôi tạo GroovyShell, tạo Binding và gọi shell.run(script,args). Đối với các thử nghiệm xác nhận các điều kiện lỗi, System.exit() làm cho JVM (và kiểm tra) thoát ra.

Có cách nào khác để sử dụng System.exit() để thoát khỏi Tập lệnh Groovy không? Tôi đã thử nghiệm với việc ném các ngoại lệ không bị bắt, nhưng điều đó cắt đầu ra và luôn tạo mã trạng thái 1.

Trong các trường hợp thử nghiệm của mình, tôi cũng đã thử nghiệm sử dụng System.metaClass.static.invokeMethod để không thoát JVM. như một hack xấu xí.

Trả lời

9

imho System.metaClass.static.invokeMethod có vẻ ổn. Đó là thử nghiệm, và hack là tốt ở đây.

Ngoài ra bạn có thể tạo wrapper của riêng bạn xung quanh nó, như:

class ExitUtils { 

    static boolean enabled = true 

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

} 

và vô hiệu hóa nó để kiểm tra.

+0

Cảm ơn. Tôi đã dọn dẹp công việc 'System.metaClass.static.invokeMethod' của mình và nó có vẻ ít bị hack hơn nhiều. – Patrick

4

Đây là kỹ thuật mà chúng tôi đã sử dụng cuối cùng.

Chúng tôi không thể bỏ qua cuộc gọi đến System.exit() vì tập lệnh sẽ tiếp tục chạy. Thay vào đó, chúng tôi muốn ném một ngoại lệ với mã trạng thái mong muốn. Chúng tôi ném một (tùy chỉnh) ProgramExitException khi System.exit() được gọi trong các thử nghiệm của chúng tôi

class ProgramExitException extends RuntimeException { 

    int statusCode 

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

thì chúng ta đánh chặn System.exit() để ném ngoại lệ này

/** 
* 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) 
    } 
} 

và cuối cùng chúng tôi có GroovyShell bắt bất kỳ ProgramExitException và trả về mã trạng thái từ phương thức 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) 
    } 
} 

Các thử nghiệm của chúng tôi có thể trông đơn giản, chúng tôi không cần thay đổi hành vi mà chúng tôi mong đợi chạy trên dòng lệnh.

assertEquals 'Unexpected status code', 0, shell.run(script,[arg1, arg2]) 
assertEquals 'Unexpected status code', 10, shell.run(script,[badarg1, badarg2]) 
Các vấn đề liên quan