【问题标题】:Carmine connection error during tests测试期间的胭脂红连接错误
【发布时间】:2016-12-20 19:15:15
【问题描述】:

我有一个带有一些简单 compojure-api 路由的 luminus 项目。 我添加了carmine 与redis 服务器通信,使用wcar* 宏(在services.clj 中定义)对其进行调用,一切正常。

现在我正在尝试添加一些测试,但似乎 redis 连接在这些测试期间无法正常工作,因为我收到lein test 的此错误:

ERROR Carmine 连接错误

clojure.lang.ExceptionInfo:胭脂红连接错误{}

由于它在devprod 环境中工作,我认为这与test 环境中缺少env 负载有关,但我没有找到解决它的方法。

这些是正在使用的代码的相关部分:

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)

【问题讨论】:

  • 你能展示你的app.config/env定义吗?
  • 我刚刚将其添加到问题中

标签: clojure compojure luminus compojure-api carmine


【解决方案1】:

您正在使用mount 来管理您的应用程序状态生命周期。我认为您没有在测试中调用(mount/start),因此您的app.config/env 状态未正确初始化。另一方面,当您启动应用程序时,(mount/start) 可能会被调用,因此它可以正常工作。

【讨论】:

  • 你是对的。尝试在测试开始时记录 env 值会导致:;; Testing app.test.handler ;; ... #object[mount.core.DerefableState 0x6bf86b4a {:status :ready, :val #object[mount.core.NotStartedState 0x59eac843 '#'app.config/env' is not started (to start all the states call mount/start)]}]。我会用工作代码更新问题。
  • 我认为您还应该在夹具中的测试之后调用(mount/stop) 以进行适当的测试隔离(最好在finally 块中)。
猜你喜欢
  • 2017-10-14
  • 1970-01-01
  • 2017-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多