clojurespeclj

Pass value to each speclj spec?


I'd like to start a service before each spec and shut it down after each spec. At the same time I want each spec to be able to use the service from the spec. For example (which doesn't work):

(describe
  "Something"

  (around [it]
          (let [service (start!)]
            (try
              (it)
              (finally
                (shutdown! service)))))

  (it "is true"
      ; Here I'd like to use the "service" that was started in the around tag
      (println service) 
      (should true))

  (it "is not false"
      (should-not false)))

How can I do this?


Solution

  • I can't see a direct support for it in speclj and its internal design doesn't allow for extending it with such functionality. However, you can just use dynamic scope to achieve it:

    (declare ^:dynamic *service*)
    
    (describe
      "Something"
    
      (around [it]
        (binding [*service* (start!)]
          (try
            (it)
            (finally
              (shutdown! *service*)))))
    
      (it "is true"
        (println *service*) 
        (should true))
    
      (it "is not false"
        (should-not false)))
    

    The *service* var will be bound to the result of (start!) within the binding scope.