Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to require a namespace programmatically

I'm working on a Liberator project in Clojure. I've defined a series of routes which return JSON data computed by logic in some other namespace. I would like to be able to change the namespace that implements the logic programmatically so I can do something like this:

JAVA_OPTS='-DgameLogicNamespace=foo.logic.mock' lein ring server-headless 8080

I am currently doing it like this:

(ns foo.routes
  (:require [compojure.core :refer :all]
            [liberator.core :as lib :refer [defresource request-method-in]]
            [liberator.representation :refer [ring-response]]))

(require
 (vec
  (cons (symbol (System/getProperty "gameLogicNamespace" "foo.logic.real"))
        '[:as logic])))

This works, but feels a bit clunky. Is there an idiomatic way to accomplish what I want?

One of my main motivations is actually for unit testing routes with mock data, so if there's a nice solution for providing the mock logic only in tests (and not as a JVM system property), suggestions are welcome.

like image 911
Josh Glover Avatar asked Apr 01 '26 20:04

Josh Glover


1 Answers

One of my main motivations is actually for unit testing routes with mock data, so if there's a nice solution for providing the mock logic only in tests (and not as a JVM system property), suggestions are welcome.

If you haven't already, take a look at ring-mock for some nice utilities to generate mock requests to test your Ring handlers.

If you're interested in providing mock versions of functions that provide the implementation of your application logic during unit tests, consider using with-redefs; it's pretty much custom-made for this purpose.

(ns my-app.handlers-test
  (:require [clojure.test]
            [my-app.handlers :as h]
            [my-app.logic :as l]
            [ring.mock.request :as r]))

(deftest test-simple-handler
  (with-redefs [l/my-complicated-logic #(update-in % [:a] inc)]
    (is (= {:a 2}
           (h/my-handler (r/request :post "/foo" {:a 1}))))))
like image 64
Alex Avatar answered Apr 08 '26 19:04

Alex



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!