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

标签 unit-testing clojure macros core.async

我正在尝试在使用 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/

相关文章:

unit-testing - 观察者模式的单元测试

clojure 部分文件/createTempFile

c++ - TRUE 和 FALSE 宏的奇怪定义

java - Java中的方面和宏有什么区别

java - 映射结构 : mocking nested mapper

具有优秀OOP设计的PHP项目,供学习使用

flutter - ClojureDart : Execution error at cljd. 编译器/load-libs-info (compiler.cljc :126). EOF 读取时

objective-c - xcode宏 objective-c 不工作

javascript - 用于单元测试的 LoopbackJS 注册模型

graph - 从 Clojure 中表示为向量的树中获取边