测试生成Datomic交易数据的代码

时间:2016-10-01 16:12:09

标签: testing clojure transactions datomic

我在Clojure中编写了一些生成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"}]

但是,我不能简单地将输出与期望值进行比较,因为我永远不会知道在代码生成之前创建的确切DbId,并且每次调用(d / tempid ...)时结果都不同。因此,等式检查将返回false。

有没有人想过以一般方式做到这一点的最好方法,所以它可以针对任何类型的交易数据运行(例如使用嵌套交易数据)?

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

非常感谢任何建议。

谢谢,

1 个答案:

答案 0 :(得分: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

在您的情况下,请将:a替换为:db/id

如果您希望更深入地检查交易结果,可以使用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值是什么,但如果您确实需要,可以检查是否相等(参见上次测试)。