Тестирование кода, генерирующего данные о транзакциях с использованием данных

Я написал код на 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.

Есть ли у кого-нибудь мысли о том, как лучше всего сделать это в целом, чтобы его можно было запускать с любыми данными транзакции (например, работает с данными вложенных транзакций)?

Я подумал о создании собственного типа MockDbId с переопределенным методом equals, а затем переопределении (d / tempid ...) в тестах, чтобы вернуть этот фиктивный идентификатор, но это не похоже на хороший способ добиться желаемого поведения.

Любой совет будет очень признателен.

Спасибо,

Мэтт.


person Matthew Gretton    schedule 01.10.2016    source источник


Ответы (1)


Вы можете решить эту проблему, используя функцию wild-match? из библиотеки Tupelo.

Образцы:

(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. Вот пример из модульного теста:

  ; 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, но вы можете проверить равенство, если вам действительно нужно (см. Последний тест).

person Alan Thompson    schedule 01.10.2016
comment
Привет, Алан - Спасибо за ответ. Ваше решение отлично работает для первого блока кода в моем примере, но не дает мне функциональности, необходимой для других частей. например, во втором блоке я не могу полностью игнорировать значения, так как мне нужно убедиться, что временный идентификатор на первой карте такой же, как и во второй. Это невозможно сделать с помощью подстановочного знака. - person Matthew Gretton; 03.10.2016
comment
Я обновил ответ, чтобы показать, как вы можете проверить значения после транзакции, хотя я не уверен, каков вариант использования для этого. - person Alan Thompson; 03.10.2016