有没有办法在clojure中测试System/exit?

Ton*_*aik 3 clojure

我有运行的代码,(System/exit 0)我想测试该部分代码.我试过测试它,with-redefs但我发现我不允许对Java方法这样做.我该如何测试呢?

Art*_*ldt 9

对不起,你不能直接模拟这个功能,虽然像所有好的CS问题*你可以通过添加一个额外的间接级别来解决它:

(defn exit-now! [] 
   (System/exit 0))
Run Code Online (Sandbox Code Playgroud)

然后在你的测试中你可以 - 现在重新调用对clojure函数exit的调用.

(with-redefs [exit-now! (constantly "we exit here")]
    (is (= "we exit here" (code that calls exit))))
Run Code Online (Sandbox Code Playgroud)

也许你可以推动该功能的开发人员远离在项目中深入调用System/exit的做法.

*当然除了性能问题.


Mic*_*zyk 7

如果你真的需要测试调用System/exit,你可以使用a SecurityManager来禁止它们然后捕获结果SecurityExceptions:

(System/setSecurityManager
  (proxy [SecurityManager] []
    (checkExit [status]
      (throw (SecurityException.
               (str "attempted to exit with status " status))))
    (checkCreateClassLoader []
      true)
    (checkPermission [_]
      true)))

(System/exit 5)
;> SecurityException attempted to exit with status 5  user/eval6/fn--11 (NO_SOURCE_FILE:2)

(try (System/exit 5) (catch SecurityException e :foo))
;= :foo
Run Code Online (Sandbox Code Playgroud)

但是,一般情况下,将方法调用包装在像Arthur建议的函数中往往是更为理智的方法.