我正在研究 Liberator Clojure 中的项目。我已经定义了一系列路由,这些路由返回由其他命名空间中的逻辑计算的 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 系统属性),欢迎提出建议。
最佳答案
One of my main motivations is actually for unit testing routes with mock data, so if there's a nice solution for providing the mock logic only in tests (and not as a JVM system property), suggestions are welcome.
如果您还没有,请查看 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}))))))
关于clojure - 如何以编程方式要求命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23584223/