Datatypes that implement a single method can be more simply represented as ordinary functions, e.g.
(defn real-provider ...) (defn fake-provider ...) (defn load-page [provider ...] (let [foo (provider)] ...)) That being said, you have other options: In clojure.test you can using `binding` to stub out functions within your tests. Lazytest <http:// github.com/stuartsierra/lazytest> has explicit support for stubbing out functions during testing. -S On Oct 11, 6:06 pm, "Felix H. Dahlke" <f...@ubercode.de> wrote: > Hi, > > I'm new to Clojure, using it for a reasonably sized project for the > first time, and I'm trying to do test-driven development. > > While it does work well technically - clojure.test is very nice to use > and feels a lot like JUnit 4's assertThat() - I'm wondering if I'm > trying to program Java in Clojure. > > Here's an example: > > I'm writing a class (Um. I mean, a ... namespace? Well, a horde of > functions.) that accesses web pages from a backend, which can e.g. take > these from the filesystem or from a database. In Java or C++, I'd use an > interface for that and create one implementation for the filesystem and > one for the database: > > interface Provider { > String loadPage(String name); > > } > > This is possible in Clojure: > > (defprotocol Provider > (load-page [this name]) > > It can be implemented using deftype: > > (deftype DatabaseProvider [] > Provider > (load-page [this name] > (have-fun-with-the-database))) > > And I can call it like this: > > (load-page (DatabaseProvider.) "foo") > > Feels a little weird (especially since all examples of defprotocol and > deftype use camel case for type names), but works. > > Back to my question: Am I trying to do Java in Clojure? Is there a more > Lisp-y way to do this? > > As you may have suspected, this design wasn't my initial intention, it > was driven by TDD: This allows me to create a mock implementation > against which I can write my test cases without having having to depend > on external resources. Typical TDD design. In fact, there will only be > one backend for now. > > This made me wonder if test-driven development was desirable in Clojure > at all, or even in functional programming in general. > > There's a few articles on the issue. Many seem to be from Clojure > newcomers, asking questions themselves, and none handles design issues > like mock objects [1]. > > One guy basically said that he stopped doing TDD because the REPL makes > it possible to test specific functions directly [2]. I can see how he > says that the *driven* aspect of TDD can be performed by the REPL, but I > find it too inconvenient for extensive use. > > Bob Martin says that, because functional programming differs from > object-oriented programming (In my opinion, these paradigms are > compatible - did he mean imperative programming?), test-driven > development has to start by testing the details, and work up to testing > the big picture. TDD in e.g. Java starts with the big picture and moves > down. I don't understand his points completely, but if he's right, this > might be a fundamental problem for TDD in functional languages. > > One guy partly disagrees with him on some matters, but doesn't really > mention the bottom-up thing [4]. > > What are your thoughts on these issues? Is anybody here doing TDD in > Clojure? Is anybody against it? > > [1]:http://www.magpiebrain.com/2010/02/16/struggling-with-test-driven-clo... > [2]:http://s-expressions.com/2009/07/28/clojure-the-repl-and-test-driven-... > [3]:http://blog.objectmentor.com/articles/2010/06/03/tdd-in-clojure > [4]:http://ericlefevre.net/wordpress/2010/06/04/bob-martin-on-tdd-in-cloj... > > signature.asc > < 1KViewDownload -- 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