2016-09-30 51 views
4

我正在採取我在球拍中處理異常的第一步,並且希望編寫一個單元測試,它將檢查某個過程是否爲特定輸入引發異常。對異常的球拍測試

以下是我已經有:

的程序,這將引發異常:

(define (div-interval x y) 
    ;; EXERCISE 2.10 
    ; exception handling 
    (with-handlers 
    ([exn:fail:contract:divide-by-zero? 
     (lambda (exn) 
     (displayln (exn-message exn)) 
     #f)]) 

    (if (or 
     (>= (upper-bound y) 0) 
     (<= (lower-bound y) 0)) 

     (raise 
     (make-exn:fail:contract:divide-by-zero 
     "possible division by zero, interval spans zero" 
     (current-continuation-marks))) 

     (mul-interval 
     x 
     (make-interval 
      (/ 1.0 (upper-bound y)) 
      (/ 1.0 (lower-bound y))))))) 

單元測試:

(require rackunit) 

(define exercise-test 
    (test-suite 
    "exercise test suite" 

    #:before (lambda() (begin (display "before")(newline))) 
    #:after (lambda() (begin (display "after")(newline))) 

    (test-case 
     "checking interval including zero" 
     (check-exn 
     exn:fail:contract:divide-by-zero? 
     (div-interval 
      (make-interval 1.0 2.0) 
      (make-interval -3.0 2.0)) 
     "Exception: interval spans zero, possible division by zero"))) 

(run-test exercise-test) 

有這一些測試測試套件,但它們用於其他過程,所以我沒有將它們包含在此代碼中。當我運行我的程序,我得到下面的輸出:

before 
possible division by zero, interval spans zero 
after 
'(#<test-success> #<test-success> #<test-success> #<test-success> #<test-error>) 

<test-error>是在這個職位的測試案例。

看來程序不會引發異常。

這是因爲我在我的程序中有一個handler,它返回#f,因此已經「吃」了異常?

我通常會如何編寫一個單元測試用於引發異常?

回答

4

你是絕對正確的,你的代碼沒有引發異常,因爲with-handler抓到它並返回#f。如果你想with-handler重新拋出異常給你,你需要使用raise,使你的代碼看起來是這樣的:

(define (div-interval x y) 
    (with-handlers 
    ([exn:fail:contract:divide-by-zeor? 
     (lambda (e) 
     <do-stuff> 
     (raise e))]) 
    <function-body>) 

現在,你的處理器將繼續運行,但最終它會重新引發你的例外。

至於測試它,你是絕對正確的,check-exn是正確的方式去做。除了因爲check-exn是一個過程,你需要用你的代碼在一個thunk使它看起來像:

(require rackunit) 
(check-exn 
    exn:fail:contract:divide-by-zero? 
    (lambda() 
    (div-interval 
     (make-interval 1.0 2.0) 
     (make-interval -3.0 2.0)))) 
+0

你的意思是我必須包裝一個'lambda'表達式中的劃分函數調用,爲了不評價該部門立即,但使它成爲'check-exn'內調用的函數? – Zelphir

+0

是的,那正是我的意思。 –

+0

工作正常,謝謝!我注意到,在命令行上,我仍然得到打印的異常的上下文。這是使用'check-exn'的正常情況,還是因爲我在中間捕獲了異常並重新提升它? – Zelphir