I was reading Clojure in Action chapter 8 about TDD and experimented with the stubbing macro. It uses the dynamic binding mechanism to stub functions. Alas, in Clojure 1.3 it is not possible to use the binding mechanism for non-dynamic vars, so the stubbing macro doesn't work in most cases, unless you explicitly declare the var which points to a function dynamic. Then I wondered how stubbing is done in Midje and tried to find the source for 'provided', but I couldn't find it. So here it goes:
How is 'provided' implemented in a fact in Midje? Can someone explain this in detail?
Source: (StackOverflow)
I'm trying to write some unit tests for my clojure function (I'm using clojure.test, but I can switch to midje if necessary).
I have a function that reads like :
(defn GenerateNodes
[is-sky-blue? hot-outside? name]
(cond
(is-sky-blue? name) (generate-sky-nodes)
(hot-outside?) (generate-hot-nodes)))
when unit testing this function, I want to write the following test case :
(deftest when-sky-blue-then-generate-sky-nodes
(let [is-sky-blue true]
(GenerateNodes (fn[x] println "sky nodes generated."))
(is (= true Was-generate-hot-nodes-called?))
How can I assert that the function generate-sky-nodes was called ? or not ?
I would use a mocking framework in C# or java, but I don't know about clojure.
Source: (StackOverflow)
I have a number of midje facts that have setup/teardowns that are almost, but not quite, entirely the same.
(against-background [(before :contents (setup!)) (before :contents (data)) (before :facts (set-access)) (after :contents (teardown!)]
(facts "about this thing i am testing "
; ...
))
(against-background [(before :contents (setup!)) (before :contents (data)) (before :facts (set-other-access)) (after :contents (teardown!)]
(facts "about this other thing i am testing "
; ...
))
I would like to wrap the backgrounds into something reusable and preferably paramterizable so I can reuse them, but having trouble doing so. Midje tells me anything other than the above is not the expected background form.
Source: (StackOverflow)
When I make a test using an outer let clause to structure some definitions and calls, the stubs don't work the way I'd expect. For example:
This test fails
(fact "blah"
(let [x (meth1 123)]
x => 246
(provided
(meth2 123) => 246)))
With this code
(defn meth2 [x]
(prn "meth2" x)
(* 3 x))
(defn meth1 [x]
(let [y (meth2 x)]
y))
Am I not supposed to use let
statements with midje? I can't understand how to get these to pass without removing the let
.
Source: (StackOverflow)
I'm trying to include midje "facts" alongside my source code in a project which uses aot. Trying to access the repl or run the project results in the following error, I've included a minimal sample project which reproduces the issue. Thanks for any help!
project.clj
(defproject test-midje "0.1.1"
:description "Why doesn't midje work?"
:min-lein-version "2.0.0"
:source-paths ["src/clj"]
:repl-options {
:timeout 120000
}
:main org.midjetest.core
:profiles {:dev {:dependencies [[midje "1.5.0"]]}}
:aot [org.midjetest.core])
src/clj/org/midjetest/core.clj
(ns org.midjetest.core
(:require [midje.sweet :refer [fact facts]]))
(defn addtwo [a] (+ 2 a))
(fact "addtwo adds two to numbers"
(addtwo 3) => 5)
(defn -main
"testing with main"
([] (println (addtwo 5))))
lein run
or lein repl
give the following error:
$ lein repl
Compiling org.midjetest.core
Exception in thread "main" java.lang.ExceptionInInitializerError
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:270)
at clojure.lang.RT.loadClassForName(RT.java:2056)
at clojure.lang.RT.load(RT.java:419)
at clojure.lang.RT.load(RT.java:400)
at clojure.core$load$fn__4890.invoke(core.clj:5415)
at clojure.core$load.doInvoke(core.clj:5414)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.core$load_one.invoke(core.clj:5227)
at clojure.core$load_lib.doInvoke(core.clj:5264)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.core$apply.invoke(core.clj:603)
at clojure.core$load_libs.doInvoke(core.clj:5298)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invoke(core.clj:603)
at clojure.core$require.doInvoke(core.clj:5381)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at org.midjetest.core$loading__4784__auto__.invoke(core.clj:1)
at org.midjetest.core__init.load(Unknown Source)
at org.midjetest.core__init.<clinit>(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:270)
at clojure.lang.RT.loadClassForName(RT.java:2056)
at clojure.lang.RT.load(RT.java:419)
at clojure.lang.RT.load(RT.java:400)
at clojure.core$load$fn__4890.invoke(core.clj:5415)
at clojure.core$load.doInvoke(core.clj:5414)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.core$load_one.invoke(core.clj:5227)
at clojure.core$load_lib.doInvoke(core.clj:5264)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.core$apply.invoke(core.clj:603)
at clojure.core$load_libs.doInvoke(core.clj:5298)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invoke(core.clj:603)
at clojure.core$require.doInvoke(core.clj:5381)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at user$eval5.invoke(form-init9180276290836069038.clj:1)
at clojure.lang.Compiler.eval(Compiler.java:6511)
at clojure.lang.Compiler.eval(Compiler.java:6500)
at clojure.lang.Compiler.eval(Compiler.java:6500)
at clojure.lang.Compiler.load(Compiler.java:6952)
at clojure.lang.Compiler.loadFile(Compiler.java:6912)
at clojure.main$load_script.invoke(main.clj:283)
at clojure.main$init_opt.invoke(main.clj:288)
at clojure.main$initialize.invoke(main.clj:316)
at clojure.main$null_opt.invoke(main.clj:349)
at clojure.main$main.doInvoke(main.clj:427)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.lang.Var.invoke(Var.java:419)
at clojure.lang.AFn.applyToHelper(AFn.java:163)
at clojure.lang.Var.applyTo(Var.java:532)
at clojure.main.main(main.java:37)
Caused by: java.lang.NullPointerException
at java.util.concurrent.ConcurrentHashMap.hash(ConcurrentHashMap.java:333)
at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:988)
at clojure.lang.Namespace.find(Namespace.java:188)
at clojure.core$find_ns.invoke(core.clj:3659)
at clojure.core$the_ns.invoke(core.clj:3691)
at clojure.core$ns_name.invoke(core.clj:3698)
at midje.Bootstrap$bootstrap.invoke(Bootstrap.clj:8)
at midje.sweet__init.load(Unknown Source)
at midje.sweet__init.<clinit>(Unknown Source)
... 53 more
Exception in thread "Thread-4" clojure.lang.ExceptionInfo: Subprocess failed {:exit-code 1}
at clojure.core$ex_info.invoke(core.clj:4327)
at leiningen.core.eval$fn__3532.invoke(eval.clj:226)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at leiningen.core.eval$eval_in_project.invoke(eval.clj:326)
at clojure.lang.AFn.applyToHelper(AFn.java:167)
at clojure.lang.AFn.applyTo(AFn.java:151)
at clojure.core$apply.invoke(core.clj:619)
at leiningen.repl$server$fn__7443.invoke(repl.clj:201)
at clojure.lang.AFn.applyToHelper(AFn.java:159)
at clojure.lang.AFn.applyTo(AFn.java:151)
at clojure.core$apply.invoke(core.clj:617)
at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1788)
at clojure.lang.RestFn.invoke(RestFn.java:425)
at clojure.lang.AFn.applyToHelper(AFn.java:163)
at clojure.lang.RestFn.applyTo(RestFn.java:132)
at clojure.core$apply.invoke(core.clj:621)
at clojure.core$bound_fn_STAR_$fn__4102.doInvoke(core.clj:1810)
at clojure.lang.RestFn.invoke(RestFn.java:397)
at clojure.lang.AFn.run(AFn.java:24)
at java.lang.Thread.run(Thread.java:744)
Source: (StackOverflow)
Found some odd behavior in midje, not sure if it's midje related, or due to my misunderstanding of some clojure constructs, but it's puzzling:
Inside a facts statement, a for loop is not getting called:
(ns t1
(:require [midje.sweet :refer :all ] )
)
(facts
(println "ok") ; -- this prints fine
(for [val '(1 2 3)] (println val)) ; this does not
(fact "junk"
(> (.length "aaaaha") 3) => true ))
Thought maybe it had something to do with the for being overwritten in the ns but calling clojure.core/for behaves similarly.
Source: (StackOverflow)
I am trying to setup autotest for midje. Currently, running lein midje works. However running lein midje :autottest gives me the stack trace below.
I run through my different namespaces and they all compile
Compiling 1 source files to /Users/oloo/Documents/work/cmp/target/classes
warning: Supported source version 'RELEASE_6' from annotation processor 'org.sonatype.guice.bean.scanners.index.SisuIndexAPT6' less than -source '1.7'
1 warning
======================================================================
Loading (cmp.models cmp.util cmp.repository.orderdeliveryschedule-repository cmp.repository.facility-repository cmp.repository.facility-cycle-data-repository cmp.views.layout cmp.routes.facility cmp.repository.item-repository cmp.repository.procurement-plan-repository cmp.routes.login cmp.excel-util cmp.repository.district-repository cmp.repository.facility-order-repository cmp.repository.facility-issue-repository cmp.routes.import-data cmp.test-util cmp.routes.item cmp.routes.district cmp.repository.user-repository cmp.routes.reports cmp.repository.category-repository cmp.routes.facility-issue cmp.routes.procurement-plan cmp.routes.facility-order cmp.handler cmp.repl cmp.repository.level-repository)
log4j:WARN No appenders could be found for logger (com.mchange.v2.log.MLog).
log4j:WARN Please initialize the log4j system properly.
Exception in thread "main" java.lang.Exception: No namespace: cmp.routes.item found
at clojure.core$the_ns.invoke(core.clj:3760)
at clojure.core$ns_name.invoke(core.clj:3767)
at midje.repl$on_require_failure.invoke(repl.clj:387)
at midje.data.project_state$require_namespaces_BANG_$broken_source_file_QMARK___5874.invoke(project_state.clj:65)
at midje.data.project_state$require_namespaces_BANG_$shorten_ns_list_by_trying_first__5877.invoke(project_state.clj:69)
at midje.data.project_state$require_namespaces_BANG_.invoke(project_state.clj:75)
at midje.data.project_state$react_to_tracker_BANG_$fn__5889.invoke(project_state.clj:98)
at midje.repl$namespace_stream_checker.invoke(repl.clj:403)
at midje.data.project_state$react_to_tracker_BANG_.invoke(project_state.clj:94)
at midje.data.project_state$mkfn_COLON_scan_and_react$fn__5893$fn__5894.invoke(project_state.clj:109)
at clojure.lang.Atom.swap(Atom.java:37)
at clojure.core$swap_BANG_.invoke(core.clj:2160)
at midje.data.project_state$mkfn_COLON_scan_and_react$fn__5893.invoke(project_state.clj:107)
at midje.data.project_state$load_everything.invoke(project_state.clj:117)
at midje.repl$autotest.doInvoke(repl.clj:511)
at clojure.lang.RestFn.invoke(RestFn.java:397)
at midje.repl$autotest.doInvoke(repl.clj:524)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at user$eval6032.invoke(NO_SOURCE_FILE:1)
at clojure.lang.Compiler.eval(Compiler.java:6619)
at clojure.lang.Compiler.eval(Compiler.java:6609)
at clojure.lang.Compiler.eval(Compiler.java:6582)
at clojure.core$eval.invoke(core.clj:2852)
at clojure.main$eval_opt.invoke(main.clj:308)
at clojure.main$initialize.invoke(main.clj:327)
at clojure.main$null_opt.invoke(main.clj:362)
at clojure.main$main.doInvoke(main.clj:440)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.lang.Var.invoke(Var.java:419)
at clojure.lang.AFn.applyToHelper(AFn.java:163)
at clojure.lang.Var.applyTo(Var.java:532)
at clojure.main.main(main.java:37)
Subprocess failed
Source: (StackOverflow)
Background
I'm new to Clojure so please forgive any glaring errors. I am trying to test some Clojure data access code that uses the redis-clojure library. Whilst my integration tests will, of course, test the full stack I do not want my unit tests to be reliant upon connecting to a redis server instance. Mocking the actual Redis commands with Midje appears to be relatively straight-forward however, the connection macro is more difficult to deal with.
Suggestions needed
What can't seem to do or find via the Midje documentation is way of mocking the redis connection or redefining the macro. The relevant top level connection macro from core.clj is:
(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)
I don't appear to be able to redefine the macro in my test code and wrapping the macro in a function doesn't get me any further forwards as I still need the body to be executed to produce my result. What I'd ideally like to do is execute the body passed into the connection macro and discard the rest of the macro. Any ideas?
Source: (StackOverflow)
I'm trying to use the Midje testing framework for Clojure on the Travis CI service.
The project.clj
looks like this:
(defproject my-project "0.1.0-SNAPSHOT"
:description "Example"
:dependencies [[org.clojure/clojure "1.3.0"]]
:dev-dependencies [[midje "1.3.0"]
[lein-midje "1.0.7"]])
I added a .travis.yml
file:
language: clojure
script: "lein midje"
Running lein midje
locally (Ubuntu 11.10) works fine, but on Travis CI the build fails with the following exception:
Exception in thread "main" java.lang.RuntimeException: java.lang.NoSuchMethodError: clojure.lang.KeywordLookupSite.<init>(ILclojure/lang/Keyword;)V
at clojure.lang.Util.runtimeException(Util.java:165)
at clojure.lang.Compiler.eval(Compiler.java:6476)
at clojure.lang.Compiler.eval(Compiler.java:6431)
at clojure.core$eval.invoke(core.clj:2795)
at clojure.main$eval_opt.invoke(main.clj:296)
at clojure.main$initialize.invoke(main.clj:315)
at clojure.main$script_opt.invoke(main.clj:339)
at clojure.main$main.doInvoke(main.clj:426)
at clojure.lang.RestFn.invoke(RestFn.java:482)
at clojure.lang.Var.invoke(Var.java:417)
at clojure.lang.AFn.applyToHelper(AFn.java:178)
at clojure.lang.Var.applyTo(Var.java:518)
at clojure.main.main(main.java:37)
Caused by: java.lang.NoSuchMethodError: clojure.lang.KeywordLookupSite.<init>(ILclojure/lang/Keyword;)V
at leiningen.util.paths$native_arch_path.<clinit>(paths.clj:32)
at leiningen.util.paths__init.load(Unknown Source)
at leiningen.util.paths__init.<clinit>(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at clojure.lang.RT.loadClassForName(RT.java:2030)
at clojure.lang.RT.load(RT.java:417)
at clojure.lang.RT.load(RT.java:398)
at clojure.core$load$fn__4610.invoke(core.clj:5386)at clojure.core$load.doInvoke(core.clj:5385)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.core$load_one.invoke(core.clj:5200)
at clojure.core$load_lib.doInvoke(core.clj:5237)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.core$apply.invoke(core.clj:602)
at clojure.core$load_libs.doInvoke(core.clj:5271)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invoke(core.clj:602)
at clojure.core$require.doInvoke(core.clj:5352)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at leiningen.core$loading__4414__auto__.invoke(core.clj:1)
at leiningen.core__init.load(Unknown Source)
at leiningen.core__init.<clinit>(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at clojure.lang.RT.loadClassForName(RT.java:2030)
at clojure.lang.RT.load(RT.java:417)
at clojure.lang.RT.load(RT.java:398)
at clojure.core$load$fn__4610.invoke(core.clj:5386)
at clojure.core$load.doInvoke(core.clj:5385)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.core$load_one.invoke(core.clj:5200)
at clojure.core$load_lib.doInvoke(core.clj:5237)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.core$apply.invoke(core.clj:602)
at clojure.core$load_libs.doInvoke(core.clj:5271)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invoke(core.clj:604)
at clojure.core$use.doInvoke(core.clj:5363)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at user$eval1.invoke(NO_SOURCE_FILE:1)
at clojure.lang.Compiler.eval(Compiler.java:6465)
... 11 more
Why does the error occur on Travis CI, but not my machine? What can I do to fix this?
Source: (StackOverflow)
Here's the situation: I'm trying to unit test function A that calls function B. Function B is called in a slingshot try+ block and under certain circumstances it can throw using a slingshot throw+. I want to mock function B in a midje test so that it returns something that the catch in the try+ block will actually catch. I can't seem to create the right thing to throw though. Here's a substantially abbreviated sketch of the code and the test:
(defn function-A
[param]
(try+
(function-B param)
(catch [:type :user-not-found]
(do-something))))
(defn function-B
[param]
(throw+ [:type :user-not-found]))
(fact "do-something is called"
(function-A "param") => (whatever is the result of calling do-something)
(provided
(function-B "param") =throws=> (clojure.lang.ExceptionInfo. "throw+: {:type :user-not-found}"
{:object {:type :user-not-found}, :environment {}}
nil)))
The ExceptionInfo that I'm throwing seems to be roughtly the right thing. I can see this when my application is running through numerous prn statements. However, whatever I try, I can't get the test to work.
I also tried the bit of code below in a repl to see whether I could understand the problem. However, whilst both pieces of code seem to involve identical Exceptions, only one (the pure slingshot one) manages to catch and print "caught it". I think that if I could understand why one works and the other doesn't, I would be able to solve the problem with the unit test.
(try+
(try
(throw+ {:type :user-not-found})
(catch Exception e
(prn "Caught: " e)
(prn "Class: " (.getClass e))
(prn "Message: " (.getMessage e))
(prn "Cause: " (.getCause e))
(prn "Data: " (.getData e))
(throw e)))
(catch [:type :user-not-found] p
(prn "caught it")))
(try+
(try
(throw (clojure.lang.ExceptionInfo. "throw+: {:type :user-not-found}"
{:object {:type :user-not-found}, :environment {}}
nil))
(catch Exception e
(prn "Caught: " e)
(prn "Class: " (.getClass e))
(prn "Message: " (.getMessage e))
(prn "Cause: " (.getCause e))
(prn "Data: " (.getData e))
(throw e)))
(catch [:type :user-not-found] p
(prn "caught it")))
Source: (StackOverflow)
Consider the following (minimal) leiningen project
./project.clj:
(defproject repro "0.1.0-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.5.1"]
[midje "1.5.1"]])
./repro/src/repro/core.clj:
(ns repro.core)
./repro/test/repro/core_test.clj:
(ns repro.core-test
(:require [repro.core :refer :all]
[midje.sweet :refer :all]))
(facts "about numbers"
(fact "trivial"
1 => 1) )
If I have the leiningen midje plugin installed, this runs at the command prompt as follows:
lein clean
lein midje
~~> All checks (1) succeeded.
However, if I import the leiningen project into Intellij 12.1.5 Community Edition, I get a fat stack trace:
Exception in thread "main" java.lang.ExceptionInInitializerError
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:270)
...
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.lang.NullPointerException
at java.util.concurrent.ConcurrentHashMap.hash(ConcurrentHashMap.java:333)
at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:988)
at clojure.lang.Namespace.find(Namespace.java:188)
at clojure.core$find_ns.invoke(core.clj:3728)
at clojure.core$the_ns.invoke(core.clj:3760)
at clojure.core$ns_name.invoke(core.clj:3767)
at midje.Bootstrap$bootstrap.invoke(Bootstrap.clj:8)
at midje.sweet__init.load(Unknown Source)
at midje.sweet__init.<clinit>(Unknown Source)
... 37 more
Looks like La Clojure + Intellij can't find some of midje's prerequisites, which is odd, because La Clojure is running classpaths out of the leiningen .m2
directory.
I've looked for a midje plugin for Intellij, but no luck so far.
I need this because although I am happy to use just emacs + leiningen, my team wants Intellij.
Source: (StackOverflow)
I am trying to write a midje test using ring-mock to do a post to a liberator endpoint. I can successfully write a test for get requests but I can't seem to pass data to the post, I only get back the malformed response. Here is the meat of the code that I have.
;; ====
; Resource
;; ====
(def users (atom [{:id 1 :name "User One"} {:id 2 :name "User Two"}]))
(defn malformed-users? [context]
(let [params (get-in context [:request :multipart-params])]
(and
(empty? (get params "id"))
(= (get-in context [:request :request-method]) :post))))
(defresource all-users []
:allowed-methods [:get :post]
:available-media-types ["application/json"]
:handle-ok (fn [_] {:users @users})
:malformed? (fn [context] (malformed-users? context))
:handle-malformed "You need to pass both a valid name and id"
:post! (fn [context]
(let [params (get-in context [:request :multipart-params])]
(swap! users conj {:id (bigint (get params "id")) :name (get params "name")})))
:handle-created (fn [_] {:users @users}))
(defroutes user-routes
(ANY "/users" [_] (all-users)))
;; ====
; Test
;; ====
(fact "Get request to users endpoint returns desired content"
(let [response (user-routes (mock/request :post "/users" {:id "3" :name "TestGuy"}))]
(:status response) => 201
(get-in response [:headers "Content-Type"]) => "application/json;charset=UTF-8"))
Source: (StackOverflow)
I have written the following Midje test:
(fact (followers-minus-friends ...name...) => ["Dude"]
(provided (idset show-followers ...name...) => #{1 2 3}
(idset show-friends ...name...) => #{1 2}
(userinfos #{3}) => [{:screen_name "Dude"}]))
to test the following function (in a different namespace):
(defn followers-minus-friends [screenname]
(let [difference-ids (difference (idset show-followers screenname)
(idset show-friends screenname))
userinfos (userinfos difference-ids)]
(map :screen_name userinfos)))
The test may seem pretty useless, but I'm just trying to get accustomed to Midje. Somehow, the function idset just gets executed, which I wanted to prevent by providing a return value in the provided-clause. What could be an explanation for this?
EDIT: I have uploaded the project to Github here, in case you want to try to reproduce the above situation: https://github.com/Borkdude/twitter-utils
Source: (StackOverflow)
I'm trying to test my routing in isolation using Midje. For some routes that hit the database I have no trouble using (provided ...)
to isolate the route from a real db call. I've introduced Friend for authentication and I've been unable to fake the call to the credential function.
My credential function looks like this (It's implemented like this because I don't want it getting called just yet):
(defn cred-fn
[creds]
(println (str "hey look I got called with " creds))
(throw (Exception.)))
The middleware for the routes then look like this:
(def app
(-> app-routes
(wrap-json-body {:keywords? true :bigdecimals? true})
wrap-json-response
(wrap-defaults defaults)
(friend/authenticate
{:unauthorized-handler json-auth/login-failed
:workflows [(json-auth/json-login
:login-uri "/login"
:login-failure-handler json-auth/login-failed
:credential-fn auth/cred-fn)]})
(ring-session/wrap-session)))
I've also tried without using the auth-json-workflow, the implementation for the routes looks almost identical and I can add that if it helps but I get the same result.
And then my tests look like this (using ring-mock):
(defn post [url body]
(-> (mock/request :post url body)
(mock/content-type "application/json")
app))
(fact "login with incorrect username and password returns unauthenticated"
(:status (post "/login" invalid-auth-account-json)) => 401
(provided
(auth/cred-fn anything) => nil))
(fact "login with correct username and password returns success"
(:status (post "/login" auth-account-json)) => 200
(provided
(auth/cred-fn anything) => {:identity "root"}))
I then get the following output running the tests:
hey look I got called with {:password "admin_password", :username "not-a-user"}
FAIL at (handler.clj:66)
These calls were not made the right number of times:
(auth/cred-fn anything) [expected at least once, actually never called]
FAIL "routes - authenticated routes - login with incorrect username and password returns unauthenticated" at (handler.clj:64)
Expected: 401
Actual: java.lang.Exception
clojure_api_seed.authentication$cred_fn.invoke(authentication.clj:23)
hey look I got called with {:password "admin_password", :username "root"}
FAIL at (handler.clj:70)
These calls were not made the right number of times:
(auth/cred-fn anything) [expected at least once, actually never called]
FAIL "routes - authenticated routes - login with correct username and password returns success" at (handler.clj:68)
Expected: 200
Actual: java.lang.Exception
clojure_api_seed.authentication$cred_fn.invoke(authentication.clj:23)
So from what I can see the provided statement is not taking effect, and I'm not sure why. Any ideas?
Source: (StackOverflow)
I'm trying to use midje to test a future, but I can't seem to get it to work.
The code looks like
(defn foo []
(let [f (future (bar))]
(baz @f))
With a test like
(fact
(foo) => ..a..
(provided
(bar) => ..b..
(baz ..b..) => ..a..))
This fails, saying that bar never gets called. Any way around this?
Source: (StackOverflow)