6

状況は次のとおりです: 関数 B を呼び出す関数 A を単体テストしようとしています。関数 B を midje テストでモックして、try+ ブロックの catch が実際にキャッチするものを返すようにしたいと考えています。しかし、投げるのに適したものを作成できないようです。コードとテストの大幅な簡略化されたスケッチを次に示します。

(defn function-A
  [param]
  (try+
    (function-B param)
    (catch [:type :user-not-found]
      (do-something))))

(defn function-B
  [param]
  (throw+ [:type :user-not-found]))

(fact "do-something is called"
  (function-A "param") => (whatever is the result of calling do-something)
  (provided
    (function-B "param") =throws=> (clojure.lang.ExceptionInfo. "throw+: {:type :user-not-found}"
                                                                {:object {:type :user-not-found}, :environment {}}
                                                                nil)))

私がスローしている ExceptionInfo は、ほぼ正しいようです。これは、アプリケーションが多数の prn ステートメントを実行しているときに確認できます。しかし、私が何をしようとしても、テストを機能させることができません。

また、問題を理解できるかどうかを確認するために、repl で以下のコードを少し試しました。ただし、コードの両方の部分には同一の例外が含まれているように見えますが、1 つ (純粋なスリングショットのもの) だけが「キャッチされた」をキャッチして出力することができます。一方が機能し、他方が機能しない理由を理解できれば、単体テストで問題を解決できると思います。

(try+
  (try
    (throw+ {:type :user-not-found})
    (catch Exception e
      (prn "Caught:  " e)
      (prn "Class:   " (.getClass e))
      (prn "Message: " (.getMessage e))
      (prn "Cause:   " (.getCause e))
      (prn "Data:    " (.getData e))
      (throw e)))
  (catch [:type :user-not-found] p
    (prn "caught it")))

(try+
  (try
    (throw (clojure.lang.ExceptionInfo. "throw+: {:type :user-not-found}"
                                        {:object {:type :user-not-found}, :environment {}}
                                        nil))
    (catch Exception e
      (prn "Caught:  " e)
      (prn "Class:   " (.getClass e))
      (prn "Message: " (.getMessage e))
      (prn "Cause:   " (.getCause e))
      (prn "Data:    " (.getData e))
      (throw e)))
  (catch [:type :user-not-found] p
    (prn "caught it")))
4

2 に答える 2

4

それは本当に遅い応答ですが、次の解決策はどうですか:

(defn ex+ [cause]
  (try
    (throw+ cause)
    (catch Throwable ex
      ex)))

使用例:

(broken-fn) =throws=> (ex+ {:type :user-not-found})

利点は、Slingshot の内部実装に依存しないことです。

于 2016-02-05T07:44:09.967 に答える
2

スロー可能なものを生成する方法についてのスリングショットのコード(ここここここthrowを参照)に従って、単にingするときに機能するスロー可能なものを生成するための次の(やや工夫された)方法を見つけました。

(s/get-throwable (s/make-context {:type :user-not-found} "throw+: {:type :user-not-found}" (s/stack-trace) {}))

あなたの例から期待していた結果をレンダリングします。

(try+
  (try
    (throw (s/get-throwable (s/make-context {:type :user-not-found} "throw+: {:type :user-not-found}" (s/stack-trace) {})))
    (catch Exception e
      (prn "Caught:  " e)
      (prn "Class:   " (.getClass e))
      (prn "Message: " (.getMessage e))
      (prn "Cause:   " (.getCause e))
      (prn "Data:    " (.getData e))
      (throw e)))
  (catch [:type :user-not-found] p
    (prn "caught it")))

それが役に立てば幸い。

于 2013-06-12T17:53:30.403 に答える