Reputation: 10695
How can I test for a function that throws an expected exception? Here is the function that throws the exception:
(defn seq-of-maps?
"Tests for a sequence of maps, and throws a custom exception if not."
[s-o-m]
(if-not (seq? s-o-m)
(throw (IllegalArgumentException. "s-o-m is not a sequence"))
(if-not (map? (first s-o-m))
(throw (IllegalArgumentException. "s-o-m is not a sequence of maps."))
true)))
I want to design a test like the following in which an exception is thrown and caught and then compared. The following does not work:
(deftest test-seq-of-maps
(let [map1 {:key1 "val1"}
empv []
s-o-m (list {:key1 "val1"}{:key2 "val2"})
excp1 (try
(seq-of-maps? map1)
(catch Exception e (.getMessage e)))]
(is (seq-of-maps? s-o-m))
(is (not (= excp1 "s-o-m is not a sequence")))))
I am getting these errors:
Testing util.test.core
FAIL in (test-seq-of-maps) (core.clj:27)
expected: (not (= excp1 "s-o-m is not a sequence"))
actual: (not (not true))
Ran 2 tests containing 6 assertions.
1 failures, 0 errors.
Obviously, I am missing something about writing tests. I am having trouble figuring that out. My project was set up with lein new, and I am running the tests with lein test.
Thanks.
Upvotes: 22
Views: 8030
Reputation: 17761
The last assertion in your test is incorrect; it should be (is (= excp1 "s-o-m is not a sequence"))
since map1 isn't a seq of maps.
Aside from that, it's probably clearer to use (is (thrown? ..))
or (is (thrown-with-msg? ...))
to check for thrown exceptions.
Example:
(t/is (thrown? java.lang.ClassCastException (s/valid? ::sut/int-value "x"))))
Note that you just write classname as a symbol. Use java.lang.Exception
if you don't care about the exact Exception
.
Upvotes: 22