2015-12-05 48 views
1

我想写这样一个测试:使用core.async进行测试 - 在测试中刷新块?

(deftest login-form-rendering 
    (async done (with-redefs [http/post fake-login-success] 
     (with-mounted-component (c/login-form login!) 
      (fn [c div] 
      (.click (.getElementById js/document "Login")) 
      (is (= (:page @app-state) :location))))) 
     (done))) 

我有这样的模拟:

(defn fake-login-success [& _] 
    (let [ch (chan) 
     response {:status 200}] 
    (go (>! ch response) 
     ch))) 

登录功能做到这一点:

(defn login! [username password] 
    (go (let [result (->> {:form-params {:username @username :password @password}} 
         (http/post "/api/login") 
         (<!)) 
      {status :status body :body} result] 
     (case status 
      401 (swap! app-state assoc :page :bad-login) 
      200 (swap! app-state assoc :page :location))))) 

登录表单试剂接收onClick回调的组件。应用程序状态是一个全局访问的原子。

我面临的问题是,登录内的去块!永远不会执行。有什么我需要做的冲洗频道或什么?

我看到这里还有一个类似的未答复的问题:Testing core.async code in ClojureScript。一个区别似乎是我的测试代码中没有明确的通道。这是由cljs-http文章生成的。

回答

3

我相信你的问题是一个错位的括号。

(let [ch (chan) 
     response {:status 200}] 
    (go (>! ch response) 
     ch)) 

let的返回值是go块的信道。它是不含任何​​添加剂的通道,因为:

  1. go块试图把对非缓冲通道,需要一些其它的操作,以“满足”,并做了补充采取以它自己的执行进行。
  2. ch在词汇上隐藏在外面的世界,所以不存在可以执行互补操作的操作。

如果事情不知怎么搞的,从它采取(或我们增加了一个缓冲区ch所以先放成功),ch将返回通道上放。

(let [ch (chan) 
     response {:status 200}] 
    (go (>! ch response)) 
    ch) 

let的返回值是ch,没有附加的信道包裹它。 go-block停在试图放在ch上,直到像你的测试一样从你的测试中获取。

然而,因为我们最终只是希望构建一个通道具有恒定上,go本身似乎是一个简单的解决方案:

(defn fake-login-success [& _] 
    (go {:status 200})