2014-01-24 34 views
0

如果一个函数说,(get-user-details user-id)返回像一个嵌套的地图:如何测试一个返回嵌套地图的函数?

{:first-name "John" 
    :last-name "Doe" 
    :age 24 
    :address {:house-no "24/3" 
      :street "Peter Parker Street" 
      :city "New York" 
      :country "USA"}} 

我应该如何测试?

该顺序与=运算符有关,而且我不希望某些额外键的顺序或存在与测试用例的传递有关。

什么是这种情况下的一般测试策略?

+2

在地图中,顺序无关紧要。由'='调用的映射的等价概念是它们具有相同数量的元素,并且一个元素的所有键/值对都在另一个中。 –

+0

至于额外的键,我不明白这是如何发生的,如果你嘲笑数据,但你需要一个递归子图。 –

+0

你可以使用sets检查所需的键是否在映射中:'(subset?(set [:first-name])(set(keys {:first“John”}))' – edbond

回答

1

在工作中,我们使用了一些相当大的嵌套地图,我们使用Prismatic's Schema library两个测试结构,来描述自己结构到其他人类。它很好地处理了可选键之类的事情,并且定义很好地组成了可读性。

这里是从他们的网站的样品:

(s/validate 
    Data 
    {:a {:b 123 
     :c "ABC"}}) 
;; Exception -- Value does not match schema: 
;; {:a {:b (not (instance? java.lang.String 123)), 
;;  :c (not (integer? "ABC"))}, 
;; :d missing-required-key} 

验证我倾向于使用get-inselect-keys较大嵌套结构中测试的特定值的数据的结构之后。对于映射的每个逻辑块都有一个断言,所以当事情中断时错误是有意义的。

1

您可以创建这样的函数:

(defn my-eq [expected actual] 
    (let [actual-subset (select-keys actual (keys expected))] 
    (= actual-subset expected))) 

它选择从您的实际结果基于预期的哈希键的按键,然后对它们进行比较。

编辑

不过,我很少写测试这个样子。相反,我宁愿出打破各自的东西放在单独的测试,这样的错误信息提供有意义的反馈:

(is (= "Donna" (:name actual))) 
(is (= 23 (:age actual))) 
(let [address (:address actual)] 
    (is (= 90210 (:zip address))))