how to write test cases in clojure - clojure

i am beginner in clojure
I wrote
(expect true (valid? "henry" "as#gmail.com" "9999999999" "tesxt message"))
in my (ns clojuregeek.test.contact)
when i run the test cases by lein test in clojure i found:--
lein test clojuregeek.test.contact
Ran 0 tests containing 0 assertions.
0 failures, 0 errors.
failure in (contact.clj:32) : clojuregeek.test.contact
(expect
true
(valid? "henry" "as#gmail.com" "9999999999" "tesxt message"))
act-msg: exception in actual: (valid? "henry" "as#gmail.com" "9999999999" "tesxt message")
threw: class java.lang.ClassCastException - clojure.lang.Var$Unbound cannot be cast to java.util.concurrent.Future
noir.validation$get_errors$doInvoke (validation.clj:94)
noir.validation$errors_QMARK_$doInvoke (validation.clj:140)
on (contact.clj:34)
on (contact.clj:32)
Ran 1 tests containing 1 assertions in 178 msecs
0 failures, 1 errors.

While developing a petri net simulator in Clojure, the testing environment Midje was the best choice to write useful and simple testcases. Maybe you just take a look at this...
Testcases are really simple. You just create your facts in test/core_tests.clj like:
(ns your-namespace.core-tests
(:use midje.sweet)
:require [your-namespace.core :as core])
(fact "Testing valid?"
(core/valid? "henry" "as#gmail.com" "9999999999" "tesxt message") => true)
;; some more facts...
For preparation you need to modify your project.clj:
(defproject your-project "0.1.0-SNAPSHOT"
:description ""
:url "http://example.com/FIXME";TODO
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.5.1"]
[midje "1.6.2"]]
:main ^:skip-aot your-project.core
:target-path "target/%s"
:profiles {:uberjar {:aot :all}
:dev {:dependencies [[midje "1.6.2"]]
:plugins [[lein-midje "3.1.3"]]}})
After this you can start a new terminal window and type in your project folder first lein deps and after this:
lein midje :autotest
and Midje is going to run through your test every time you save a file in your project folder.
In my opinion one of the best solutions to write simple and useful testcases.

Related

Clojure dependencies for tests only

In my project.cli I have a dependency on clj-http that is used for tests only, with clj-http.client.
When I look at the uberjar file created for that project, I see that the class fils associated with this dependency are included. That makes the jar file bigger than it need be.
So, is there a way to define a dependency in clojure such that it is only used during tests, and is not included in the uberjar?
I know that I could do this in a pom.xml, but the pom.xml is generated when using clojure, so I only have recourse to something that works in the project.clj file.
To add more colour, my project.clj looks like this
(defproject aproject "0.1.0-SNAPSHOT"
:description "A project"
:dependencies [[org.clojure/clojure "1.8.0"]
[org.clojure/data.json "0.2.6"]
[compojure "1.5.0"]
[hiccup "1.0.5"]
[http-kit "2.1.18"]
[org.clojure/tools.logging "0.3.1"]
[ch.qos.logback/logback-classic "1.1.7"]
[ring/ring-devel "1.4.0"]]
:plugins [[lein-ring "0.9.7"]]
:ring {:handler aproject.core/app-routes}
:main ^:skip-aot aproject.core
:target-path "target/%s"
:resources-paths ["resources/"]
:profiles {:uberjar {:aot :all}
:dev {:dependencies [[peridot "0.4.3"]
[midje "1.8.3"]]
:plugins [[lein-midje "3.2.1"]]
:aliases {"test" ["midje"]}}
:test {:dependencies [[clj-http "3.5.0"]
[midje "1.8.3"]]
:plugins [[lein-midje "3.2.1"]]}
})
I am running the tests like this:
lein with-profile test midje :filters dt
What I am seeing is:
Exception in thread "main" java.io.FileNotFoundException: Could not locate midje/util/ecosystem__init.class or midje/util/ecosystem.clj on classpath., compiling:(/private/var/folders/7l/0fwd_7ls1m19q3_z1_tgg1w80000gn/T/form-init7253661442775183594.clj:1:125)
at clojure.lang.Compiler.load(Compiler.java:7391)
The filter probably does not affect this, but just in case the test looks like this:
(ns aproject.deployment.core
(:require [midje.sweet :refer :all]
[clj-http.client :as client]
[peridot.core :as p]
[clojure.data.json :as json]
[front-end.core :as fe]))
(facts "'aproject' deployed" :dt
(let [response (client/get "http://localhost:8080/ping")]
(response :status) => 200
))
I can see that the test profile is being triggered, and I seem to have the dependency for midje, and the plugin, but ...?
Thanks
Nathan
Add it to the :test profile, then run your tests with lein with-profile test midje :filters dt. Generate your uberjar as usual, lein uberjar and it shouldn't include the extra files.

Trouble testing Leiningen plugin against latest Clojure

I am trying to update lein-resource to use clojure.spec which requires the alpha version of Clojure [org.clojure/clojure "1.9.0-alpha13"]. When I add the dependency it compiles ok but the REPL and testing use the lein version of Clojure 1.8.0.
If I set :eval-in-leiningen to false, it respects the Clojure dependency.
How can I test a lein plugin with a different version of Clojure without disabling the ability for it to run as a plugin?
I'm guessing that your project.clj is getting overridden by your file ~/.lein/profiles.clj. Mine looks like this:
> cat ~/.lein/profiles.clj
{ :user {
:plugins [
[com.jakemccrary/lein-test-refresh "0.16.0"]
[jonase/eastwood "0.2.3"]
[lein-ancient "0.6.0"]
[lein-codox "0.9.3"]
[lein-exec "0.3.6"]
]
:dependencies [
[org.clojure/clojure "1.9.0-alpha13"]
]
:test-refresh { :quiet true
:changes-only true }
; :jvm-opts ["-Xms1g" "-Xmx4g" ] ; "-server"
}
}
I'm assuming your project.clj should look something like this:
(defproject clj "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [
[org.clojure/clojure "1.9.0-alpha13"]
[tupelo "0.9.9"]
]
:java-source-paths ["/home/alan/xpr/src"]
:main ^:skip-aot clj.core
:target-path "target/%s"
:profiles {:dev {:dependencies [[org.clojure/test.check "0.9.0"]] }
:uberjar {:aot :all}}
)
Fix up your ~/.lein/profiles.clj and you should have no problem.
Turns out the problem is :eval-in-leiningen true in the project.clj. It is a bit of a catch-22. If it is there, it forces the test to run with the version of Clojure defined with the installed with lein. If it is removed, the lein dependecies in the code are not resolved.

How to create an uberjar correctly with "lein uberjar"?

if I use lein run the project is no problem.
But when I use jave -jar blog.jar after lein uberjar It happen exceptions.
16-Jul-20 11:28:05 DESKTOP-C3SC9AR INFO [slf4j-timbre.adapter] - >> starting.. *db*
Exception in thread "main" java.lang.RuntimeException: could not start [*db*] due to
.....
Caused by: java.lang.Exception: :jdbc-url, :datasource, or :datasource-
AND my project.clj file
(defproject blog "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:dependencies ....
:min-lein-version "2.0.0"
:uberjar-name "blog.jar"
:jvm-opts ["-server"]
:main blog.core
:migratus {:store :database}
:plugins [[lein-environ "1.0.1"]
[migratus-lein "0.2.0"]]
:profiles
{:uberjar {:omit-source true
:env {:production true}
:aot :all
:source-paths ["env/prod/clj"]}
:dev [:project/dev :profiles/dev]
:test [:project/test :profiles/test]
:project/dev ...
:project/test ...
:profiles/dev {:env {:database-url "jdbc:postgresql://localhost/blog?user=postgres&password=root"}}
:profiles/test {}})
Maybe it can't find the key of "database-url"?
Data provided via environment settings in project.clj are not provided when you use java directly. It's your responsibility to make sure the environment settings visible to the app provide any credentials or connection info needed.
It could look something like:
DATABASE_URL="jdbc...." java -jar my-project-standalone.jar

GUI Using Seesaw

I am trying to make a small window using Seesaw for Clojure. I have created a project "sample" using Leiningen.
lein new app sample
I have made added the dependency in the project file.
(defproject sample "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.6.0"] [seesaw "1.4.4"]]
:main ^:skip-aot sample.core
:target-path "target/%s"
:profiles {:uberjar {:aot :all}})
My source file is as follows:
(ns sample.core
(:gen-class)
(:require [seesaw.core :as seesaw]
[seesaw.dev :as dev]))
(def window (seesaw/frame
:title "First Example"
:content "hello world"))
(dev/show-options window)
But when I run it I keep getting an error: clojure.lang.Compiler$CompilerException: java.lang.RuntimeException: No such namespace: dev, compiling:(C:\Users\A\sample\src\sample\core.clj:10:1)
I followed your instructions and it worked fine for me, so long as I left the -main definition in place.

I can't run a basic clojurescript.test sample

I'm trying to run a basic test with
https://github.com/cemerick/clojurescript.test
I've created a simple project such as:
(defproject sampleproj "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.5.1"]
[org.clojure/clojurescript "0.0-2014"]
]
:plugins [[lein-cljsbuild "1.0.0"]
[com.cemerick/clojurescript.test "0.2.2"]]
:cljsbuild {:builds [{:source-paths ["src-js" "test-js"]
:compiler {:output-to "target/cljs/testable.js"
:optimizations :whitespace
:pretty-print true}}]
:test-commands {"unit-tests" ["phantomjs" :runner
"this.literal_js_was_evaluated=true"
"target/cljs/testable.js"]}}
)
Both folders src-js and test-js exist since I intend to put all my clojurescript files there.
In my test-js/sampleproj folder I copied the sample test in the documentation:
(ns sampleproj.sampletest
(:require-macros [cemerick.cljs.test
:refer (is deftest with-test run-tests testing test-var)])
(:require [cemerick.cljs.test :as t]))
(deftest somewhat-less-wat
(is (= "{}[]" (+ {} []))))
(deftest javascript-allows-div0
(is (= js/Infinity (/ 1 0) (/ (int 1) (int 0)))))
(with-test
(defn pennies->dollar-string
[pennies]
{:pre [(integer? pennies)]}
(str "$" (int (/ pennies 100)) "." (mod pennies 100)))
(testing "assertions are nice"
(is (thrown-with-msg? js/Error #"integer?" (pennies->dollar-string 564.2)))))
Now if I try to run the tests
-> % lein cljsbuild test
Compiling ClojureScript.
Running ClojureScript test: unit-tests
ReferenceError: Can't find variable: cemerick
phantomjs://webpage.evaluate():2
phantomjs://webpage.evaluate():5
phantomjs://webpage.evaluate():5
ReferenceError: Can't find variable: cemerick
phantomjs://webpage.evaluate():2
phantomjs://webpage.evaluate():5
phantomjs://webpage.evaluate():5
Subprocess failed
I'm fairly new to clojurescript so probably I'm missing something.
Update:
My environment
-> % lein -v
Leiningen 2.3.4 on Java 1.7.0_06 Java HotSpot(TM) 64-Bit Server VM
-> % phantomjs -v
1.9.2
-> % java -version
java version "1.7.0_06"
Java(TM) SE Runtime Environment (build 1.7.0_06-b24)
Java HotSpot(TM) 64-Bit Server VM (build 23.2-b09, mixed mode)
Are macros located right into clj sources ?
After that th compiler shoud compiler you cemeric macros to javascript.
You propably have dependencies right in project.clj
This hasn't been answered, so I will. You need to specify your dependency for clojurescript.test : [com.cemerick/clojurescript.test "0.3.1"]