2016-09-30 12 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) 

この中にいくつかのより多くのテストがあります。テストスイートですが、他の手続き用ですので、私はこのコードに含めませんでした。私は私のプログラムを実行すると、私は次のような出力が得られます。<test-error>はこの記事では、テストケースのためである

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

例外が発生しないようです。

#fを返す私の手続きにhandlerがあり、それですでに例外を "食べた"ので、これはですか?

私は通常、発生した例外の単体テストをどのように記述しますか?

答えて

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は手続きである、あなたはそれがどのように見える作りサンクであなたのコードをラップする必要があるため除い:

(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

関連する問題