背景
我是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)
我似乎无法在测试代码中重新定义宏,并且将宏包装在函数中并不能使我有任何进一步的发展,因为我仍然需要执行主体以产生结果。我理想地要做的是执行传递到连接宏的主体,并丢弃其余的宏。有任何想法吗?
最佳答案
我建议在Midje mailing list上问您的问题(然后在此处发布最终答案)。不知道您要测试什么,就很难给出建议。也许(遵循Freeman和Pryce的Growing Object-Oriented Software(确实适用于Clojure-实际上,支持这种风格是我编写Midje的原因)),您想将问题分为两部分。首先,您要构建一组隔离Redis的功能。您可以使用与实际数据库一起进行的缓慢而繁琐的直接测试来测试这些功能是否正常工作。
这些功能将隐藏连接以及对包装宏的需求。
然后,您可以使用Midje先决条件来测试您的代码是否正确调用了隔离功能。
Avdi Grimm的Objects on Rails是另一本书,在谈论隔离数据库方面做得不错。
注意:我对Redis一无所知,但是其他一些Clojure-> database库省去了具有吸引力的包装宏(with-server
)。取而代之的是,它们走有状态的路线,并拥有一个保持连接的全局变量,就像(例如)Ruby数据库库ActiveRecord(隐式)和Sequel(显式)一样。尽管不那么纯净,但它似乎使生活(包括测试)更加简单。在Midje中,这种联系可以用一个元常量来表示。
关于macros - 使用Clojure + Midje重新定义宏操作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10391002/