2016-10-01 43 views
1

我已经用Clojure写的一些代码,产生Datomic交易数据,我想要写一些测试,以检查是否按预期的方式创建的数据。测试代码产生Datomic交易数据

从本质上讲,我需要能够证明相对于交易数据:

[{:db/id (d/tempid :db.part/user) 
    :some-field "Bob"}] 

= 

[{:db/id (d/tempid :db.part/user) 
    :some-field "Bob"}] 

[{:db/id (d/tempid :db.part/user) 
    :ref-field (d/tempid :db.part/user -1)} 
{:db/id (d/tempid :db.part/user) 
    :ref-field (d/tempid :db.part/user -1)}] 

= 

[{:db/id (d/tempid :db.part/user) 
    :ref-field (d/tempid :db.part/user -2)} 
{:db/id (d/tempid :db.part/user) 
    :ref-field (d/tempid :db.part/user -2)}] 

[{:db/id (d/tempid :db.part/user -1) 
    :some-field "Bob"}] 

!= 

[{:db/id (d/tempid :db.part/user -2) 
    :some-field "Bob"}] 

但是,我不能简单地比较输出一个预期的值,因为我永远不会知道在c产生之前创建的确切的DbId ode,并且结果每次都会有所不同(d/tempid ...)。所以平等检查将返回错误。

没有人有在一般的方式做到这一点的最好办法的任何想法,因此它可以对任何类型的交易数据来运行(例如用嵌套事务数据的工作)?

我已经考虑用重写的equals方法创建自己的MockDbId类型,然后在测试中重新定义(d/tempid ...)以返回此模拟ID,但它不觉得是一种很好的方法来实现期望的行为。

任何意见将不胜感激。

谢谢,

马特。

回答

0

您可以使用wild-match?功能from the Tupelo library.

样解决这个问题:

(wild-match? {:a :* :b 2} 
       {:a 1 :b 2})   ;=> true 

(wild-match? [1 :* 3] 
       [1 2 3] 
       [1 9 3]))   ;=> true 

(wild-match? {:a :*  :b 2} 
       {:a [1 2 3] :b 2}) ;=> true 

在你的情况,与:db/id

取代:a如果您希望做交易结果的更深层次的检查,您可以使用tx-datoms功能。下面是一个例子from the unit test:

; Create Honey Rider and add her to the :people partition 
    (let [tx-result @(td/transact *conn* 
         (td/new-entity :people ; <- partition is first arg (optional) to td/new-entity 
          { :person/name "Honey Rider" :location "Caribbean" :weapon/type #{:weapon/knife} })) 

     tx-datoms (td/tx-datoms (live-db) tx-result) 
    ] 
    ; tx-datoms looks like: 
    ; [ {:e 13194139534328, 
    ;  :a :db/txInstant, 
    ;  :v #inst "2016-10-02T21:45:44.689-00:00", 
    ;  :tx 13194139534328, 
    ;  :added true} 
    ;  {:e 299067162756089, 
    ;  :a :person/name, 
    ;  :v "Honey Rider", 
    ;  :tx 13194139534328, 
    ;  :added true} 
    ;  {:e 299067162756089, 
    ;  :a :location, 
    ;  :v "Caribbean", 
    ;  :tx 13194139534328, 
    ;  :added true} 
    ;  {:e 299067162756089, 
    ;  :a :weapon/type, 
    ;  :v 17592186045419, 
    ;  :tx 13194139534328, 
    ;  :added true} ] 
    (is (= "Honey Rider" (:v (only (keep-if #(= :person/name (:a %)) tx-datoms))))) 
    (is (= "Caribbean" (:v (only (keep-if #(= :location  (:a %)) tx-datoms))))) 
    (is (= 1    (count (keep-if #(= :weapon/type (:a %)) tx-datoms)))) 
    (is (= 1    (count (keep-if #(= :db/txInstant (:a %)) tx-datoms)))) 
    (is (apply = (map :tx tx-datoms))) ; All datoms have the same :tx value 
) 

所以,你不事先知道:e:tx值会是什么,但你可以检查平等,如果你真的需要(见最后测试)。

+0

嗨艾伦 - 感谢您的答复。您的解决方案对我的示例中的第一个代码块正常工作,但没有为我提供其他部分所需的功能。在第二个块中,例如,我不能完全忽略这些值,因为我需要验证第一个映射中的临时ID与第二个映射中的临时ID是否相同。用通配符做这件事是不可能的。 – Sigmoidal

+0

我更新了答案,以显示如何检查事务后值,但我不确定这是什么用例。 –