2012-04-30 33 views
3

背景重新定义使用Clojure + Midje

我是新来的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#)] 
      [email protected])))) 

original code in context here

我似乎没有能够重新定义宏在我的测试代码和功能包宏没有按因为我仍然需要身体被执行来产生我的结果,所以我不会再向前走。我最想做的是执行传递给连接宏的主体,并丢弃宏的其余部分。有任何想法吗?

+0

经过这个问题,我发现https:// github。com/ptaoussanis/carmine/issues/16,然后决定对我的单元测试命中本地redis实例是完全正确的 –

回答

1

我建议你问的问题Midje mailing list(然后,当然,在这里张贴最终的答案)。不知道你想要测试什么,很难提供建议。也许(以下是Freeman和Pryce的Growing Object-Oriented Software(这确实适用于Clojure--事实上,支持这种风格是我写Midje的原因)),您想要将问题分为两部分。首先,您要构建一组隔离Redis的函数。您可以测试这些函数是否可以正常运行,并且与真正的数据库一起工作的缓慢而繁琐的直接测试。

这些函数会隐藏连接和包装宏的需要。

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

Avdi Grimm's Objects on Rails是另一本关于隔离数据库的文章。

注意:我对Redis一无所知,但其他一些Clojure->数据库库免去了智力上的包装宏(with-server)。相反,他们进入有状态路由并拥有一个保存连接的全局变量,就像(比方说)Ruby数据库库ActiveRecord(隐式地)和Sequel(显式)那样。尽管不那么纯粹,但似乎使生活(包括测试)更简单。在Midje,这种联系可以用一个metaconstant来表示。

2

我经常编写用于测试的绑定包装宏。这些宏只是将其他的东西绑定到无法测试的函数或宏。在这种情况下,我会写沿着这些线路

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

这样可以使所有的嘲讽在测试代码的东西。

+0

我似乎无法做到这一点,我得到错误“Can not dynamic bind non -dynamic var:redis.core/with-server“ – jamiei

+0

好主意。像这样的东西适合midje。 @jamiei来避免这个问题,在你自己的命名空间中引入另一个间接寻址,声明它是动态的,并且在你的测试中用绑定模拟_that_ –