Ошибка соединения Carmine во время испытаний

У меня есть проект luminus с несколькими простыми маршрутами compojure-api. я добавил carmine для связи с сервером Redis, используя wcar* макрос (определенный в services.clj) для вызова к нему, и все работает нормально.

Сейчас я пытаюсь добавить некоторые тесты, но кажется, что соединение Redis не работает должным образом во время них, потому что я получаю эту ошибку с lein test:

ОШИБКА Карминная ошибка соединения

clojure.lang.ExceptionInfo: ошибка соединения Carmine {}

Так как он работает в dev е prod среда, я думаю, что это что-то, связанное с отсутствием env загрузить в test окружающей среды, но я не нашел способ ее решить.

Это соответствующие части используемого кода:

test.clj

(ns app.test.handler
  (:require [clojure.test :refer :all]
            [ring.mock.request :refer :all]
            [app.handler :refer :all]))

(deftest test-app
  (testing "redis ping"
    (let [response ((app) (request :get "/api/redis-ping"))]
      (is (= 200 (:status response))))))

services.clj

(ns app.routes.services
  (:require [ring.util.http-response :refer :all]
            [compojure.api.sweet :refer :all]
            [schema.core :as s]
            [app.config :refer [env]]
            [clojure.tools.logging :as log]
            [mount.core :refer [defstate]]
            [taoensso.carmine :as car :refer (wcar)]))

(defmacro wcar* [& body] `(car/wcar
                           {:spec {:host (:redis-host env) :port (:redis-port env)}}
                           ~@body))

(defapi service-routes
     (context "/api" []
           :tags ["myapi"]

         (GET "/redis-ping" []
               :return String
               :summary "A redis client test."
               (ok (wcar* (car/ping "hello"))))))

handler.clj

(ns app.handler
  (:require [compojure.core :refer [routes wrap-routes]]
            [app.routes.services :refer [service-routes]]
            [compojure.route :as route]
            [app.env :refer [defaults]]
            [mount.core :as mount]
            [app.middleware :as middleware]))

(mount/defstate init-app
                :start ((or (:init defaults) identity))
                :stop  ((or (:stop defaults) identity)))

(def app-routes
  (routes
    #'service-routes
    (route/not-found
      "page not found")))


(defn app [] (middleware/wrap-base #'app-routes))

Profiles.clj

{:profiles/dev  {:env {:redis-host "127.0.0.1" :redis-port 6381}}
:profiles/test {:env {:redis-host "127.0.0.1" :redis-port 6381}}}

Config.clj

(ns app.config
  (:require [cprop.core :refer [load-config]]
            [cprop.source :as source]
            [mount.core :refer [args defstate]]))

(defstate env :start (load-config
                       :merge
                       [(args)
                        (source/from-system-props)
                        (source/from-env)]))

РЕШЕНИЕ

Добавьте текстовое крепление с помощью mount/start команда, которая выполняется перед тестами.

Добавить в test.clj:

(defn my-test-fixture [f]
  (mount/start)
  (f))

(use-fixtures :once my-test-fixture)

1 ответ

Решение

Ты используешь mount управлять жизненным циклом состояния вашего приложения. Я думаю ты не звонишь (mount/start) в ваших тестах, таким образом, ваш app.config/env состояние не инициализировано должным образом. С другой стороны, когда вы запускаете приложение (mount/start) вероятно, называется и, следовательно, он работает правильно.

Другие вопросы по тегам