使用core.async进行测试 - 在测试中刷新块?

时间:2015-12-05 18:31:06

标签: clojure clojurescript core.async reagent

我正在尝试写这样的测试:

(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的回调。 app-state是一个全局可访问的原子。

我面临的问题是登录内的阻止!从未被执行过。有什么我需要做的事情来冲洗频道或什么?

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

1 个答案:

答案 0 :(得分:4)

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

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

let的返回值是go块的频道。这是一个不包含任何内容的频道,因为:

  1. go块正在尝试放置一个无缓冲的通道,需要一些其他操作来“满足”它并执行补充操作以便继续执行它自己的执行。
  2. ch在词汇上隐藏在外部世界中,因此不存在可以执行补充拍摄的操作。
  3. 如果以某种方式从中获取了某些内容(或者我们向ch添加了一个缓冲区,以便第一次放置成功),ch将被放置在返回的通道上。

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

    let的返回值为ch,没有其他通道包装它。 go - 阻止ch - 阻止试图穿上go,直到你的测试开始接受它为止。

    但是,由于我们最终只想构建一个带有常量的通道,(defn fake-login-success [& _] (go {:status 200}) 本身似乎是最简单的解决方案:

    <jsp:useBean id="chatannotation" scope="application"
        class="websocket.chat.ChatAnnotation" />
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
        <%
            String name = (String) session.getAttribute("realname");
        %>
        <a href="chat.jsp">Game</a>
    </body>
    </html>