Как передать значение из прибора в тест с помощью clojure.test?

При использовании clojure.test use-fixture существует ли способ передать значение из функции привязки в тестовую функцию?

Ответ 1

Пара хороших вариантов - это динамическое связывание и with-redefs. Вы можете связать var с тестовым пространством имен в приборе, а затем использовать его в определении теста:

core.clj:

(ns hello.core
  (:gen-class))

 (defn foo [x]
  (inc x))

Тест/привет/core.clj:

(ns hello.core-test
  (:require [clojure.test :refer :all]
            [hello.core :refer :all]))

(def ^:dynamic *a* 4)

(defn setup [f]
  (binding [*a* 42]
    (with-redefs [hello.core/foo (constantly 42)]
      (f))))

(use-fixtures :once setup)

(deftest a-test
  (testing "testing the number 42"
    (is (= *a* (foo 75)))))

Вы можете сказать, что он работает, сравнивая вызов теста напрямую, который не использует приборы, для вызова его через run-tests:

hello.core-test> (a-test)

FAIL in (a-test) (core_test.clj:17)
testing the number 42
expected: (= *a* (foo 75))
  actual: (not (= 4 76))
nil
hello.core-test> (run-tests)

Testing hello.core-test

Ran 1 tests containing 1 assertions.
0 failures, 0 errors.
{:test 1, :pass 1, :fail 0, :error 0, :type :summary}

Этот подход работает, потому что привязки закрываются над тестами, которые они запускают, хотя они не могут фактически напрямую обращаться к тестовым функциям (обычно), поэтому имеет смысл использовать закрытие для передачи информацию к тестовому коду.

Ответ 2

Возможно, это не прямой ответ, но если ваше устройство было в любом случае :each, или вы можете согласиться с тем, что оно является приспособлением :each, вы можете просто разобраться и создать функцию set-up, возвращающую соответствующее состояние и назовите это как первую строку вашего теста, вместо использования прибора. Это может быть наилучшим подходом для некоторых обстоятельств.

(defn set-up [] (get-complex-state))

(deftest blah
   (let [state (set-up)]
     (frobnicate)
     (query state)
     (tear-down state)))