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.