如何以编程方式要求命名空间 [英] How to require a namespace programmatically

查看:111
本文介绍了如何以编程方式要求命名空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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 / getPropertygameLogicNamespacefoo.logic.real))
'[:as logic]))

这可以工作,但感觉有点笨重。是否有一个惯用的方式来完成我想要的?



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

解决方案


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


如果您还没有,请查看 ring-mock 用于生成模拟请求以测试您的Ring处理程序。



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

 (ns my-app.handlers-test 
[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)]
= {:a 2}
(h / my-handler(r / request:post/ foo{:a 1}))))))
pre>

I'm working on a Liberator project in Clojure. I've defined a series of routes which return JSON data computed by logic in some other namespace. I would like to be able to change the namespace that implements the logic programmatically so I can do something like this:

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

I am currently doing it like this:

(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])))

This works, but feels a bit clunky. Is there an idiomatic way to accomplish what I want?

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.

解决方案

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.

If you haven't already, take a look at ring-mock for some nice utilities to generate mock requests to test your Ring handlers.

If you're interested in providing mock versions of functions that provide the implementation of your application logic during unit tests, consider using with-redefs; it's pretty much custom-made for this purpose.

(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}))))))

这篇关于如何以编程方式要求命名空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆