-
Notifications
You must be signed in to change notification settings - Fork 0
Testing
In this section you will be introduced to the following Pedestal concepts:
- testing behavior code
- sharing Clojure and ClojureScript code
Before we move on to the next section, we should spend a moment thinking about testing. At this point we have some behavior and it is easy enough to test it by refreshing the browser. As an application grows this will be harder to do. It would be good to have some automated tests in place.
In the file tutorial-client/test/tutorial_client/test/behavior.clj
there are some tests which are now broken. We will replace these tests
with some of our own.
Transform functions are pure functions and are therefore very easy to test. We may create some tests for our transform function like the one shown below.
(deftest test-inc-transform
(is (= (inc-transform nil {msg/type :inc msg/topic [:my-counter]})
1))
(is (= (inc-transform 0 {msg/type :inc msg/topic [:my-counter]})
1))
(is (= (inc-transform 1 {msg/type :inc msg/topic [:my-counter]})
2))
(is (= (inc-transform 1 nil)
2)))Notice that this particular transform function does not depend on the input message. We may also want to test the application in general. Before we write this test, let's make a helper function which will extract the data model from an application object.
(defn- data-model [app]
(-> app :state deref :data-model))Everything that we need to know about an app is contained in the app object. It is educational to explore its contents.
The test below shows how to create an app and then send it one or more
messages. Once the messages are processed we can check the state of
the data model. The run-sync! function will ensure that all of the
messages have been processed before returning.
(deftest test-app-state
(let [app (app/build example-app)]
(is (test/run-sync! app [{msg/type :inc msg/topic [:my-counter]}]
:begin :default))
(is (= (data-model app)
{:my-counter 1})))
(let [app (app/build example-app)]
(is (test/run-sync! app [{msg/type :inc msg/topic [:my-counter]}
{msg/type :inc msg/topic [:my-counter]}
{msg/type :inc msg/topic [:my-counter]}]
:begin :default))
(is (= (data-model app)
{:my-counter 3}))))Once we have tests in place we can run them from the command line by running
lein test
or
lein difftest
The second command will show diffs when a test fails.
There are more advanced techniques which can be used to test our applications but for now this is good enough. Notice that even though this is behavior that will run in the browser, we are testing it as plain old Clojure code.
This works because the tutorial-client.behavior namespace is marked
as :shared and uses only Clojure code that can be compiled to ClojureScript.
(ns ^:shared tutorial-client.behavior
(:require [clojure.string :as string]
[io.pedestal.app.messages :as msg]))The tag for this step is v2.0.2.