Clojure: Using given & expect To Replace Scenarios
The functionality in expectations.scenarios was borne out of compromise.
I found certain scenarios I wanted to test, but I wasn't sure how to
easily test them using what was already available in (bare)
expectations. The solution was to add expectations.scenarios, and
experiment with various features that make testing as easy as possible.
Two years later, the features that make sense have migrated back to expectations:
- Freezing Time Added To expectations
- Interaction Based Testing Added To expectations
- redef-state Added To expectations
Below is an example of a scenario that ends with multiple expects.
(ns blog-expectations (:use expectations.scenarios)) (scenario ;;; real tests will call domain code, ;;; I avoid that here for simplicity (let [x [1 2] y (map-indexed vector x)] (expect vector? x) (expect [0 1] (first y)) (expect java.util.List y)))Using given, these scenarios are actually very easy to convert. The given + bare expectation example below tests exactly the same logic.
(ns blog-expectations (:use expectations)) (given [expected actual] (expect expected (let [x [1 2] y (map-indexed vector x)] actual)) vector? x [0 1] (first y) java.util.List y)The test coverage is the same in the second example, but it is important to note that the let will now be executed 3 times instead of 1. This isn't an issue if your tests run quickly, if they don't you may want to revisit the test to determine if it can be written in a different way.
An interesting side-effect occurred while I was converting my scenarios - I found that some of my scenarios could be broken into multiple expectations that were then easier to read and maintain.
For example, the above expectations could be written as the example below.
(ns blog-expectations (:use expectations)) (expect vector? [1 2]) (given [x y-fn] (expect x (y-fn (map-indexed vector [1 2]))) [0 1] first java.util.List identity)note: you could simplify even further and remove the given, but that's likely only due to how contrived the test is. Still, the possibility exists that some scenarios will be easily convertible to bare expectations.
Using the technique described here, I've created bare expectations for all of the scenarios in the codebase I'm currently working on - and deleted all references to expectations.scenarios.
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)