Hi everyone,

Does anyone have any experience in mocking multimethods?  I'm working
on a version control framework modeled after Git:

(def
 ^{:private true}
 patches- (ref [])

(defn patches []
  (seq @patches-))

(defn do-patch! [fn & args]
  (dosync
    (apply fn args)
    (let [patch {:fn fn
                 :args (vec args)}]
      (alter patches- conj patch)
      patch)))

I need to be able to undo recorded patches, which means at undo-time,
translating the recorded do-patch! fn and args into an undo-fn which
can be called.  If an undo-fn cannot be found, it throws an
exception.  This has to be extensible so that as I add operations, I
can add the counterpart undo-fn.  Multimethods to the rescue!

(defmulti undo-fn :fn)

(defn undo-patch [patch]
  (let [fn (undo-fn patch)]
    (dosync
      (fn)
      (alter patches- #(remove #(= patch %) %)))))

So in another package, I add the operation create-table! to the
system, which has a counterpart drop-table!:

(defn create-table!- [name columns]
  (... create table stuff ...))

(defn drop-table!- [name]
  (... drop table stuff ...))

(defn create-table! [name columns]
  (make-patch! create-table!- name columns))

(defmethod undo-fn create-table!- [patch]
  #(drop-table!- (:name patch)))

So calling undo-patch! with a patch that was the result of create-
table! will call undo-fn, which will dispatch on the :fn member of the
patch, which is create-table!-, which will end up returning an
anonymous function that calls drop-table!- with the :name from
the :args member of the patch.

OK, this all works.

But from a unit testing perspective, how do I cleanly test undo-patch!
without any undo-fn methods declared?  When testing, I just want to
know that undo-patch! attempts to resolve undo-fn, will throw an error
if it can't, and will call the anonymous function that undo-fn returns
if it can.  In other words, how do I mock undo-fn?

Thanks,
Alyssa

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to