Clojure - тесты со стратегией компонентов

Я реализую приложение с помощью компонента Stuart Sierra. Как он утверждает в README:

Наличие согласованного способа настройки и снятия всех состояний, связанных с приложением, позволяет выполнять быстрые циклы разработки без перезапуска JVM. Это также может сделать модульные тесты более быстрыми и независимыми, поскольку стоимость создания и запуска системы достаточно низка, и каждый тест может создать новый экземпляр системы.

Какова будет предпочтительная стратегия здесь? Что-то похожее на JUnit oneTimeSetUp / oneTimeTearDown или действительно между каждым тестом (похоже на setUp / tearDown)?

И если между каждым тестом есть простой способ запустить / остановить систему для всех тестов (до и после) без повторения кода каждый раз?

Изменить: пример кода, чтобы показать, что я имею в виду

(defn test-component-lifecycle [f]
  (println "Setting up test-system")
  (let [s (system/new-test-system)]
    (f s) ;; I cannot pass an argument here ( https://github.com/clojure/clojure/blob/master/src/clj/clojure/test.clj#L718 ), so how can I pass a system in parameters of a test ?
    (println "Stopping test-system")
    (component/stop s)))

(use-fixtures :once test-component-lifecycle)

Примечание: я говорю о юнит-тестировании здесь.

1 ответ

Я написал бы макрос, который берет карту системы и запускает все компоненты перед запуском тестов и останавливает все компоненты после тестирования.

Например:

(ns de.hh.new-test
 (:require [clojure.test :refer :all]
           [com.stuartsierra.component :as component]))


;;; Macro to start and stop component
(defmacro with-started-components [bindings & body]
    `(let [~(bindings 0) (component/start ~(bindings 1))]
       (try
          (let* ~(destructure (vec (drop 2 bindings)))
            ~@body)
       (catch Exception e1#)
       (finally
         (component/stop ~(bindings 0))))))

;; Test Component
(defprotocol Action
  (do-it [self]))

(defrecord TestComponent [state]
   component/Lifecycle
   (start [self]
      (println "====> start")
      (assoc self :state (atom state)))
   (stop [self]
      (println "====> stop"))

   Action
    (do-it [self]
       (println "====> do action")
       @(:state self)))

;: TEST
(deftest ^:focused component-test
   (with-started-components
      [system (component/system-map :test-component (->TestComponent"startup-state"))
       test-component (:test-component system)]

    (is (= "startup-state" (do-it test-component)))))

Запуск теста вы должны увидеть результат, как это

====> start
====> do action
====> stop

Ran 1 tests containing 1 assertions.
0 failures, 0 errors.
Другие вопросы по тегам