【问题标题】:Redefining a macro operation with Clojure + Midje使用 Clojure + Midje 重新定义宏操作
【发布时间】:2012-04-30 21:44:28
【问题描述】:

背景

我是 Clojure 的新手,所以请原谅任何明显的错误。我正在尝试测试一些使用 redis-clojure 库的 Clojure 数据访问代码。虽然我的集成测试当然会测试整个堆栈,但我不希望我的单元测试依赖于连接到 redis 服务器实例。使用Midje 模拟实际的 Redis 命令似乎相对简单,但连接宏更难处理。

需要的建议

通过Midje 文档似乎无法做或找不到的是模拟 redis 连接或重新定义宏的方式。 core.clj 的相关顶级连接宏是:

(defmacro with-server
  "Evaluates body in the context of a connection to Redis server
  specified by server-spec.

  server-spec is a map with any of the following keys:
    :host     (\"127.0.0.1\")
    :port     (6379)
    :db       (0)
    :timeout  (5000)
    :password (nil)"
  ([server-spec & body]
     `(with-connection connection# *pool* ~server-spec
        (binding [redis.vars/*channel* (make-direct-channel connection#)]
          ~@body))))

(original code in context here)

我似乎无法在我的测试代码中重新定义宏,并且将宏包装在一个函数中不会让我更进一步,因为我仍然需要执行主体来产生我的结果。我最想做的是执行传递给连接宏的主体并丢弃宏的其余部分。有任何想法吗?

【问题讨论】:

标签: macros clojure midje


【解决方案1】:

我经常为测试编写绑定包装宏。这些宏只是将其他东西绑定到无法测试的函数或宏。在这种情况下,我会按照这些思路写一些东西

(defmacro my-fake-with-server []
   ....)

(defmacro with-fake-with-server
      (binding [redis.core/with-server my-fake-with-server]
               (insert test here)))

(deftest my-test (with-fake-with-server (function-that-uses-with-server)))

这会在您的测试代码中保留所有模拟。

【讨论】:

  • 我似乎无法做到这一点,我收到错误“无法动态绑定非动态变量:redis.core/with-server”
  • 好主意。像这样的东西对我有用 midje。 @jamiei 为避免该问题,在您自己的命名空间中引入另一个间接,将其声明为 ^dynamic,并在您的测试中使用绑定模拟 that
【解决方案2】:

我建议您在Midje mailing list 上提问(当然,然后在这里发布最终答案)。在不知道您要测试什么的情况下,很难给出建议。也许(按照 Freeman 和 Pryce 的 Growing Object-Oriented Software(这确实适用于 Clojure - 事实上,支持这种风格是我编写 Midje 的原因)),您想将您的问题分成两部分。首先,您要构建一组隔离 Redis 的函数。您可以通过与真实数据库一起使用的缓慢而繁琐的直接测试来测试这些功能是否正常工作。

这些函数会隐藏连接以及对包装宏的需求。

然后您可以使用 Midje 先决条件测试您的代码是否正确调用了隔离函数。

Avdi Grimm 的 Objects on Rails 是另一本在讨论隔离数据库方面做得不错的书。

注意:我对 Redis 一无所知,但其他几个 Clojure-> 数据库库不使用具有智能吸引力的包装宏 (with-server)。相反,它们走有状态的路线并有一个保存连接的全局变量,就像(比如说)Ruby 数据库库 ActiveRecord(隐式)和 Sequel(显式)所做的那样。尽管不那么纯粹,但它似乎让生活(包括测试)变得更简单。在 Midje 中,这种联系可以用元常数来表示。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-21
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多