在 clojure 中测试函数调用或 for 语句不是 运行

tests inside function calls or for statements in clojure not running

我写的代码看起来像这样

(testing "check that for all these roles there's an alert"
    (binding [*profile* account-exceeded-limits]
      (let [overview-page (overview-container sample-form
                                              :role readonly-no-download)]
        (is (dommy/has-class?
             (-> overview-page (sel1 [:div#export-list-panel :.panel-body
                                      :.alert]))
             "alert-warning")))
      (let [overview-page (overview-container sample-form
                                              :role dataentry)]
        (is (dommy/has-class?
             (-> overview-page (sel1 [:div#export-list-panel :.panel-body
                                      :.alert]))
             "alert-warning")))
      (let [overview-page (overview-container sample-form
                                              :role editor)]
        (is (dommy/has-class?
             (-> overview-page (sel1 [:div#export-list-panel :.panel-body
                                      :.alert]))
             "alert-warning")))
      (let [overview-page (overview-container sample-form
                                              :role member)]
        (is (dommy/has-class?
             (-> overview-page (sel1 [:div#export-list-panel :.panel-body
                                      :.alert]))
             "alert-warning")))
      (let [overview-page (overview-container sample-form
                                              :role collaborator)]
        (is (dommy/has-class?
             (-> overview-page (sel1 [:div#export-list-panel :.panel-body
                                      :.alert]))
             "alert-warning")))
      (let [overview-page (overview-container sample-form
                                              :role readonly)]
        (is (dommy/has-class?
             (-> overview-page (sel1 [:div#export-list-panel :.panel-body
                                      :.alert]))
             "alert-warning")))))

我需要重构这段代码,让它更简洁。

所以我尝试了这个

(testing "check that for all these roles theres an alert"
    (for [role [dataentry readonly-no-download editor member collaborator
             readonly]]
      (let [overview-page (overview-container sample-form
                                              :role role)]
        (is (dommy/has-class?
             (-> overview-page (sel1 [:div#export-list-panel :.panel-body
                                      :.alert]))
             "alert-warning")))))

似乎没有测试运行。

我也试过这个:

(testing "check that for all these roles theres an alert"
(map (fn [role]  (let [overview-page (overview-container sample-form
                                              :role role)]
        (is (dommy/has-class?
             (-> overview-page (sel1 [:div#export-list-panel :.panel-body
                                      :.alert]))
             "alert-warning"))) [dataentry readonly-no-download editor member collaborator
             readonly])))

同样,测试似乎仍然不是 运行。

这可能是什么原因造成的?有没有办法让我做这个测试烘干机?我应该尝试使测试更干燥吗?

在 Clojure 中,formap 函数都是惰性的,并且不会 运行 直到你对输出做些什么。

因为您不关心输出,您应该将 for 转换为 doseq,它总是立即 运行s (non-lazy) 并且专为 side-effects 设计,如您所愿。

一定要收藏 the Clojure CheatSheet 并始终在浏览器选项卡中保持打开状态!

还有很多其他的great resources listed here


附录:

map 的一个非常有用的表亲是 mapv。无非就是(vec (map ...)),把map的输出强制变成一个(non-lazy)向量。在我第一次听说它之前,我已经使用 Clojure 很长一段时间了。

您同样可以使用 (vec (for ...)) 获得 for 的 non-lazy 版本。它 运行 直接类似于 doseq,而且 returns 结果序列(而不仅仅是 nil)。可以看到more details here.

虽然您的代码不是 运行 的原因已经得到解决,但我想指出 are

(are argv expr & args)

Checks multiple assertions with a template expression.
See clojure.template/do-template for an explanation of
templates.
 Example: (are [x y] (= x y)  
              2 (+ 1 1)
              4 (* 2 2))
Expands to: 
         (do (is (= 2 (+ 1 1)))
             (is (= 4 (* 2 2))))
 Note: This breaks some reporting features, such as line numbers.

这将允许这样的事情:

(testing "check that for all these roles there's an alert"
  (are [role] 
       (let [overview-page (overview-container sample-form :role role)]
         (dommy/has-class?
           (-> overview-page (sel1 [:div#export-list-panel :.panel-body :.alert]))
           "alert-warning"))
       dataentry 
       readonly-no-download 
       editor 
       member 
       collaborator 
       readonly))