如何以编程方式请求命名空间

时间:2014-05-10 17:31:44

标签: clojure namespaces

我正在Clojure的Liberator项目中工作。我已经定义了一系列路由,这些路由返回由其他命名空间中的逻辑计算的JSON数据。我希望能够以编程方式更改实现逻辑的命名空间,以便我可以执行以下操作:

JAVA_OPTS='-DgameLogicNamespace=foo.logic.mock' lein ring server-headless 8080

我目前正在这样做:

(ns foo.routes
  (:require [compojure.core :refer :all]
            [liberator.core :as lib :refer [defresource request-method-in]]
            [liberator.representation :refer [ring-response]]))

(require
 (vec
  (cons (symbol (System/getProperty "gameLogicNamespace" "foo.logic.real"))
        '[:as logic])))

这有效,但感觉有点笨重。是否有一种惯用的方式来实现我想要的目标?

我的主要动机之一实际上是使用模拟数据对单元测试路径,所以如果有一个很好的解决方案只在测试中提供模拟逻辑(而不是作为JVM系统属性),欢迎提出建议。

1 个答案:

答案 0 :(得分:1)

  

我的主要动机之一实际上是使用模拟数据对单元进行测试,因此,如果只有在测试中提供模拟逻辑(而不是作为JVM系统属性),那么这是一个很好的解决方案,欢迎提出建议。 / p>

如果您还没有,请查看ring-mock以获取一些不错的实用工具来生成模拟请求以测试您的Ring处理程序。

如果您对提供在单元测试期间提供应用程序逻辑实现的函数的模拟版本感兴趣,请考虑使用with-redefs;它是为此目的而定制的。

(ns my-app.handlers-test
  (:require [clojure.test]
            [my-app.handlers :as h]
            [my-app.logic :as l]
            [ring.mock.request :as r]))

(deftest test-simple-handler
  (with-redefs [l/my-complicated-logic #(update-in % [:a] inc)]
    (is (= {:a 2}
           (h/my-handler (r/request :post "/foo" {:a 1}))))))