【问题标题】:Testing components with async api calls by mocking the request通过模拟请求使用异步 api 调用测试组件
【发布时间】:2015-12-06 11:10:44
【问题描述】:

对于 Cljs 和 Om,我仍处于学习阶段。我正在研究编写组件测试。一些组件对我创建的 API 进行了cljs-http 调用。在测试时,我不希望这些 API 调用实际发送请求,所以我正在研究模拟请求并返回一个夹具。这是我的一个示例组件:

(defn async-component [data owner]
  (reify
    IWillMount
    (will-mount [_]
      (let [resp (go ((<! (async-call "/") :body))]
        (om/update! data [:objects] resp)))
    IRender
    (render [_]
      [:ul
        (om/build-all item-component data)])))

(defn async-call [path]
  (http/get path {:keywordize-keys true}))

请不要介意代码在语法上是否真的正确,我只是展示它的要点。

我现在要做的是测试这个 async-component 和 API 调用,看看它是否会呈现我用来模拟请求的夹具。这是怎么做到的?我知道cljs.testasync 块来测试异步代码,但所有示例都显示它测试只有go 的实际代码块,而不是在更大的上下文中。

【问题讨论】:

    标签: unit-testing clojure clojurescript om


    【解决方案1】:

    这是一种您可以使用模拟来测试您的组件的方法:

    (deftest test-async-component
      (cljs.test/async done
        (with-redefs
          [async-call (fn [path]
                        (let [mock-ch (async/chan 1)
                              fixture-data {:body {:fixture-with path :and "foobar"}})]
                          (async/put! mock-ch fixture-data)
                          mock-ch)]
          ; At this point we successfully mocked out our data source (the API call)
          ; the only task that remains is to render our Om component into DOM and inspect it.
          ; As this task requires utility fns I will reuse the ones in this blog post:
          ; http://lab.brightnorth.co.uk/2015/01/27/unit-and-browser-testing-om-clojurescript-applications/
    
          (let [c (new-container!)
                initial-data {:objects [{:initial-object 42}]}]
            ; This will mount and render your component into the DOM residing in c.
            (om/root async-component initial-data {:target c})
    
            (testing "fixture data gets put into the DOM"
              (is (= "foobar" (text (sel1 c :ul)))))
    
            ; You can add more tests in this manner, then finally call 'done'.
            (done)))))
    

    以上英文代码中采取的步骤:

    1. 编写async-call 的模拟 fn,返回一个预填充有夹具数据的通道(与原始接口相同的接口)。
    2. 模拟原始 fn(您需要引用它或完全限定 ns)。
    3. 为单元测试目的创建一个新的虚拟 DOM。
    4. 指定不是来自 API 的模拟数据(如果有)。
    5. 将您的组件渲染到 DOM 中(这将在 om/will-mount 运行时调用 async-call,将 fixture-datachan 分开)。
    6. 观察 DOM 内容。

    【讨论】:

    • 这就是我要找的。也感谢您的步骤。
    猜你喜欢
    • 2021-10-14
    • 2018-08-14
    • 2018-02-18
    • 2017-04-21
    • 1970-01-01
    • 2021-05-03
    • 1970-01-01
    • 1970-01-01
    • 2019-01-13
    相关资源
    最近更新 更多