lmotl3
lmotl3

Reputation: 647

How to get REPL to recognize tests within a map?

I have a map defined as follows:

"Arcane Golem"
    {:name        "Arcane Golem"
    :attack      4
    :health      4
    :mana-cost   3
    :type        :minion
    :set         :classic
    :rarity      :rare
    :description "Battlecry: Give your opponent a Mana 
Crystal."
    :battlecry   (fn battlecry [state minion]
                     {:test (fn []
                                (as-> (create-game [{:minions [(create-minion "Arcane Golem" :id "ag")]}]) $
                                      (battlecry $ (get-minion $ "ag"))
                                      (contains? (get-in $[:players "p1" :hand]) "Mana Crystal")))}
                     (-> (get-opponent state (:id minion))
                     (:id)
                     (add-card-to-hand state (create-card "Mana Crystal"))))}

This map is itself a key-value pair in a larger map of maps called card-definitions. As you can see, I've written a test for battlecry function below; however, when I start REPL and run all tests in this maps' namespace, it says Ran 0 tests with 0 assertions. How can I get REPL to recognize this test?

Upvotes: 0

Views: 55

Answers (1)

Alan Thompson
Alan Thompson

Reputation: 29958

You can use with-test to define a function and a unit test at the same time

; with-test is the same as using {:test #((is...)(is...))} in the meta data of the function.

(:use 'clojure.test)

(with-test
    (defn my-function [x y]
      (+ x y))
  (is (= 4 (my-function 2 2)))
  (is (= 7 (my-function 3 4))))

(test #'my-function)            ;(test (var my-function))
=> :ok

NOTE: When using with-test, the function must still be defined as a global var using defn (see example). An anonymous fn as the value of a map key will not be found by the testing machinery.

What should work is to define the function as standalone var, and then include a reference to it in the map:

{:battlecry my-function}    ; for example

Having said that, most people (myself included) prefer to have a separate testing namespace to keep the tests from cluttering the source code. I like to organize them as:

flintstones.core           ; main namespace
tst.flintstones.core       ; the unit test namespace

These are then placed in ./src and ./test subdirs of the project dir:

src/flintstones/core.clj            ; main namespace
test/tst/flintstones/core.clj       ; the unit tests

But there are other possiblities. See also the Clojure Cookbook discussion on testing.

Upvotes: 2

Related Questions