Over a million developers have joined DZone.

Clojure: Using given & expect To Replace Scenarios

DZone's Guide to

Clojure: Using given & expect To Replace Scenarios

· Java Zone ·
Free Resource

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

 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:

With those features, you should be able to convert any existing scenario to a bare expectation. What isn't covered with those features is what you should do if your scenario ends with multiple expects. This blog entry demonstrates how you can use given with a bare expectation to achieve the same test coverage.

Below is an example of a scenario that ends with multiple expects.
(ns blog-expectations
  (:use expectations.scenarios))

 ;;; 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)]
       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
                         (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.

Download Building Reactive Microservices in Java: Asynchronous and Event-Based Application Design. Brought to you in partnership with Red Hat


Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}