GithubHelp home page GithubHelp logo

pablobcb / restpect Goto Github PK

View Code? Open in Web Editor NEW

This project forked from facundoolano/restpect

0.0 2.0 0.0 199 KB

Succint and readable integration tests over RESTful APIs

License: Eclipse Public License 1.0

Clojure 100.00%

restpect's Introduction

restpect

Restpect is a small Clojure library that provides a set of functions to write succint and readable integration tests over RESTful APIs.

(require '[restpect.core :refer [created ok not-found]]
         '[restpect.json :refer [GET PUT DELETE]]
         '[clojure.test :refer [deftest]])

(deftest create-get-and-delete-user
  ;; expect 201 status response and body containing a :user-id integer
  (created
   (PUT "http://example.com/api/v1/users/john" {:email "[email protected]"})
   {:user-id integer?})

  ;; expect 200 status and body containing :user-id and :email
  (ok
   (GET "http://example.com/api/v1/users/john")
   {:user-id integer?
    :email   "[email protected]"})

  ;; expect the response body to be a collection that contains at least one
  ;; element that has a :user-id integer and the given :email
  (ok
   (GET "http://example.com/api/v1/users/")
   #{{:user-id integer?
      :email   "[email protected]"}})

  (ok (DELETE "http://example.com/api/v1/users/john"))

  ;; expect 404 status and a body with a :message string that contains "not found"
  (not-found
   (GET "http://example.com/api/v1/users/john")
   {:message #"not found"}))

Installation

Add the following to your project :dependencies:

[restpect "0.2.1"]

Reference

Request helpers

The restpect.json namespace provides wrappers around the clj-http request functions with sane defaults for JSON API requests (coerce request and response as JSON, don't throw exceptions on 4xx and 5xx responses, etc.).

All these functions have the following signature:

(POST url)
(POST url body)
(POST url body extras)

The body is passed to clj-http as the :form-params for POST, PUT, PATCH and DELETE, and as the :query-params for GET, HEAD and OPTIONS.

extras is a map of overrides passed to the clj-http call.

Assertion functions

expect

The main assertion function is restpect.core/expect:

(expect response spec)

The first argument (usually a clj-http response map, although it can be any value), will be compared against the given spec with the following criteria:

  • For maps, compare the value of each key in the spec with the value at the same key of the response, using expect recursively.
  • For sets, check that each element in the spec matches some element in the response, comparing with expect recursively. This is useful to look for an element somewhere in a list, regardless of the position.
  • For other collections, compare each element in the spec with the same element at the same position in the response, using expect recursively.
  • For functions, pass the value in the response to the spec function expecting a truthy result.
  • For Regular expressions match the spec with the actual value (using re-find).
  • For the rest of the values, expect the spec and the response values to be equal.

Example:

(expect (GET url)
        {:status 404
         :body   [{:result  nil?
                   :code    125
                   :message #"not found"}]})

This assertion is equivalent to the following:

(let [res (GET url)]
  (is (= 404 (:status res)))
  (is (nil? (get-in res [:body 0 :result])))
  (is (= 125 (get-in res [:body 0 :code])))
  (is (re-find #"not found" (get-in res [:body 0 :message]))))

As seen in the example, expect is opinionated in the sense that it makes it simple to test for values and conditions on specific fields of the reponses rather than doing an exact comparison of the payloads.

Status shorthands

restpect.core also provides a set of wrappers around expect with the names of the different HTTP response status codes: ok, created, bad-request, not-found, etc.

These helpers implicitly validate the :status value of the given response map, and can optionally take a second argument that will be compared against the response body.

Using status shorthands, the example from the previous section becomes:

(not-found (GET url)
           [{:result  nil?
             :code    125
             :message #"not found"}])

Another example:

(deftest create-and-delete-user
  (created (PUT "http://example.com/api/v1/users/john" {:email "[email protected]"}))
  (ok (GET "http://example.com/api/v1/users/john"))
  (ok (DELETE "http://example.com/api/v1/users/john"))
  (not-found (GET "http://example.com/api/v1/users/john")))

Test reporter

Restpect also provides a custom test reporter that adds request and response information to failure messages (provided by expect) and does some formatting:

example report

The report multimethod can be found in restpect.report/report and can be used with plugins that allow to override the test reporter, like eftest and lein-test-refresh:

;; project.clj
:eftest {:report restpect.report/report}
:test-refresh {:report restpect.report/report}

If you already work with a custom reporter and just want to add some request/reponse data to its output, consider adding a defmethod for :type :response, for example:

(require '[restpect.report :refer [print-response]]
         '[eftest.report.progress :as eftest]
         '[clojure.test :refer [with-test-out]])

(defmulti report :type)
(defmethod report :default [m] (eftest/report m))
(defmethod report :response [m]
  (with-test-out
    (println "\r" (repeat 80 " ") "\033[F" "\033[F")
    (print-response (:response m))))

restpect's People

Contributors

facundoolano avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.