gpt4 book ai didi

unit-testing - 如何对 clojure.core.async go 宏进行单元测试?

转载 作者:行者123 更新时间:2023-12-03 21:19:55 24 4
gpt4 key购买 nike

我正在尝试在使用 core.async go 宏时编写单元测试。天真地编写测试,如下所示,似乎 go block 内的代码没有被执行。

(ns app.core-test
(:require [clojure.test :refer :all]
[clojure.core.async :as async]))

(deftest test1 []
(let [chan (async/chan)]
(async/go
(is (= (async/<! chan) "Hello")))
(async/go
(async/>! chan "Hello"))))
我已经设法使以下工作,但它非常hacky。
(deftest test1 []
(let [result (async/chan)
chan (async/chan)]
(async/go
(is (= (async/<! chan) "Hello"))
(async/>! result true))
(async/go
(async/>! chan "Hello"))
(async/alts!! [result (async/timeout 10000)])))
关于如何正确执行此操作的任何建议?

最佳答案

测试是同步执行的,所以如果你去异步测试运行器不会。在 Clojure 中,您需要通过 <!! 阻止测试运行器,在 ClojureScript 中,您必须返回一个异步测试对象。这是我在所有异步 CLJC 测试中使用的通用辅助函数:

(defn test-async
"Asynchronous test awaiting ch to produce a value or close."
[ch]
#?(:clj
(<!! ch)
:cljs
(async done
(take! ch (fn [_] (done))))))

您使用它的测试,兼容 CLJC 并且看起来不那么“hacky”:
(deftest test1
(let [ch (chan)]
(go (>! ch "Hello"))
(test-async
(go (is (= "Hello" (<! ch)))))))

断言测试解除阻塞是一种很好的做法,尤其是在测试驱动开发期间,您希望避免锁定测试运行程序。此外,锁定是异步编程失败的常见原因,因此对其进行测试是非常合理的。

为此,我编写了一个类似于您的超时操作的助手:
(defn test-within
"Asserts that ch does not close or produce a value within ms. Returns a
channel from which the value can be taken."
[ms ch]
(go (let [t (timeout ms)
[v ch] (alts! [ch t])]
(is (not= ch t)
(str "Test should have finished within " ms "ms."))
v)))

您可以使用它来编写测试,例如:
(deftest test1
(let [ch (chan)]
(go (>! ch "Hello"))
(test-async
(test-within 1000
(go (is (= "Hello" (<! ch)))))))

关于unit-testing - 如何对 clojure.core.async go 宏进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30766215/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com