是否有任何好的库或策略来测试clojure中的多线程应用程序?

zca*_*ate 3 clojure

我很好奇是否有人提出了测试多线程应用程序的好策略.

我用midje进行了很多测试,这对于测试函数非常有用......但是我不确定如何测试多线程代码而不看起来真的很hacky:

  (fact "the state is modified by a thread call"
    (Thread/sleep 100)
    (check-state-eq *state* nil)
    (Thread/sleep 100)
    (modify-state-thread-call *state* :updated-value)
    (Thread/sleep 100)
    (check-state-eq *state* :updated-value))
Run Code Online (Sandbox Code Playgroud)

有时,由于编译时间的原因,我的测试失败了,因为状态没有及时更新,所以我必须睡得更久.理想情况下,我想要一种方法来写:

  (fact "the state is modified by a thread call"
    (modify-state-thread-call *state* :updated-value) 
     =leads-to=> (check-state-eq *state* :updated-value))
Run Code Online (Sandbox Code Playgroud)

并远离睡眠.有策略可以做到吗?

小智 5

如果*state*在此示例中是clojure引用类型之一,则可以使用add-watch添加一个通知该对象的每个更改的函数:http://clojuredocs.org/clojure_core/clojure.core/add-watch

我可能建议的一种方法是在条件满足时使用手表来实现承诺.

(let [check-promise (promise)]
  (add-watch *state* :check-for-updated-value
    (fn [rkey refr _oldval newval]
       (when (some-check newval)
          (remove-watch refr rkey)
          (deliver check-promise true))))
  (modify-state-thread-call *state* :updated-value)
  (deref check-promise 1000 false))
Run Code Online (Sandbox Code Playgroud)

如果*state*获取的值some-check在1000毫秒内,则会立即返回true;如果不满足条件,则返回1000毫秒后返回false.