Case: I have json files in my
resources. I change them a lot, so I want to check them as part of a unit test.
Current solution use
s/valid? in the test. I’d like to see more precise error messages.
;; dogdb.clj (ns sample.dogdb (:require [clojure.spec.alpha :as s])) (s/def ::name string?) (s/def ::birthyear int?) (s/def ::dog (s/keys :req-un [::name ::birthyear])) (s/def ::dogs (s/coll-of ::dog)) (s/def ::dogdb (s/keys :req-un [::dogs]))
;; dogdb_test.clj (ns sample.dogdb-test (:require [clojure.data.json :as json] [clojure.java.io :as io] [clojure.spec.alpha :as s] [clojure.test :refer :all] [clojure.walk :as walk] [sample.dogdb :as dogdb] )) (defn load-json-resource [resource-path] (-> (io/resource resource-path) io/reader json/read walk/keywordize-keys)) (deftest dogdb-resource (testing "resources/dogdb.json is valid dogdb" (is (s/valid? ::dogdb/dogdb (load-json-resource "resources/dogdb.json")))))
When I run the unit test with kaocha, I get output like
FAIL in sample.dogdb-test/dogdb-resource (dogdb_test.clj:21) resources/dogdb.json is valid dogdb expected: (s/valid? ::dogdb/dogdb (load-json-resource "resources/dogdb.json")) actual: (not (s/valid? ::dogdb/dogdb (load-json-resource "resources/dogdb.json")))
I’d like to see what was actual wrong. Was a dog missing name? Was there a cat in the dog list? Was there no
:dogs entry top level?
Could I use something else than
clojure.test/is? Recommendations much welcome!