All Projects → whostolebenfrog → rest-cljer

whostolebenfrog / rest-cljer

Licence: other
A clojure wrapper for the rest driver library

Programming Languages

clojure
4091 projects

Projects that are alternatives of or similar to rest-cljer

Pester
Pester is the ubiquitous test and mock framework for PowerShell.
Stars: ✭ 2,620 (+7177.78%)
Mutual labels:  mocking
go-github-mock
A library to aid unittesting code that uses Golang's Github SDK
Stars: ✭ 63 (+75%)
Mutual labels:  mocking
Deflector.NET
A library for intercepting all method calls at runtime in nearly any .NET application.
Stars: ✭ 80 (+122.22%)
Mutual labels:  mocking
Mockiato
A strict, yet friendly mocking library for Rust 2018
Stars: ✭ 229 (+536.11%)
Mutual labels:  mocking
Mockoon
Mockoon is the easiest and quickest way to run mock APIs locally. No remote deployment, no account required, open source.
Stars: ✭ 3,448 (+9477.78%)
Mutual labels:  mocking
smockin
Dynamic API, S3 & Mail mocking for web, mobile & microservice development.
Stars: ✭ 74 (+105.56%)
Mutual labels:  mocking
Mockery
A mock code autogenerator for Golang
Stars: ✭ 3,138 (+8616.67%)
Mutual labels:  mocking
network image mock
Mock response for Image.network to help Flutter widget tests pass.
Stars: ✭ 22 (-38.89%)
Mutual labels:  mocking
Http Fake Backend
Build a fake backend by providing the content of JSON files or JavaScript objects through configurable routes.
Stars: ✭ 253 (+602.78%)
Mutual labels:  mocking
dummy
Run mock server based off an API contract with one command
Stars: ✭ 170 (+372.22%)
Mutual labels:  mocking
Axios Mock Adapter
Axios adapter that allows to easily mock requests
Stars: ✭ 2,832 (+7766.67%)
Mutual labels:  mocking
Faker
Provides fake data to your Android apps :)
Stars: ✭ 234 (+550%)
Mutual labels:  mocking
EntityFrameworkCore.AutoFixture
A library aimed to minimize the boilerplate required to unit-test Entity Framework Core code using AutoFixture and in-memory providers.
Stars: ✭ 31 (-13.89%)
Mutual labels:  mocking
Bypass Finals
Removes final keywords from source code on-the-fly and allows mocking of final methods and classes. It can be used together with any test tool such as PHPUnit or Mockery.
Stars: ✭ 228 (+533.33%)
Mutual labels:  mocking
specter-php
JSON Mocking and Testing for PHP
Stars: ✭ 18 (-50%)
Mutual labels:  mocking
Sinon Jest Cheatsheet
Some examples on how to achieve the same goal with either of both libraries: sinon and jest. Also some of those goals achievable only by one of these tools.
Stars: ✭ 226 (+527.78%)
Mutual labels:  mocking
aem-stubs
Tool for providing sample data for AEM applications in a simple and flexible way. Stubbing server on AEM, no separate needed.
Stars: ✭ 40 (+11.11%)
Mutual labels:  mocking
mockingbird
🐦 Decorator Powered TypeScript Library for Creating Mocks
Stars: ✭ 70 (+94.44%)
Mutual labels:  mocking
springmock
alternative spring mocking infrastructure
Stars: ✭ 22 (-38.89%)
Mutual labels:  mocking
universalmock
A universal mock class in Apex
Stars: ✭ 55 (+52.78%)
Mutual labels:  mocking

rest-cljer Build Status

Rest-cljer is a library that allows real mocking of http rest calls. It starts a server to listen for your requests and returns real http responses to those requests. It allows you to test your services in isolation from one another whilst actually exercising your service's code. As such it allows the service to be tested from a separate process.

A typical test scenario would be to switch out your service's dependencies to point to :restdriver-port on localhost and then use rest-cljer to mock the responses. Rest-cljer can use environ to determine :restdriver-port, so you can set your chosen port via a system property or environment variable.

Rest-cljer is a Clojure wrapper for rest-driver.

Usage

Import from clojars with:

[rest-cljer "0.2.2"]

then

(:require [rest-cljer.core :refer [rest-driven]])

An example of clojure test usage (using environ to set :rest-driver-port to 8081):

(deftest example-of-a-test
  (rest-driven [{:method :GET :url "/gety"}
                {:status 200}]
    (is (= 200 (:status (http/get "http://localhost:8081/gety"))))))

An example using a random port:

(deftest example-of-a-test
  (rest-driven [{:method :GET :url "/gety"}
                {:status 200}]
    (is (= 200 (:status (http/get (str "http://localhost:" *rest-driver-port* " /gety")))))))

An example of midje usage.

(fact "Example of testing two"
      (rest-driven
          [{:method :GET :url "/gety"}
           {:type :JSON :status 200}

           {:method :GET :url "/something"}
           {:type :JSON :status 200}]

          (client/get "http://localhost:8081/gety") => (contains {:status 200})
          (client/get "http://localhost:8081/something") => (contains {:status 200})))

Wrap your test with the (rest-driven) macro.

This expects params in the form of a vector of pairs of maps followed by a body form that is your test.

The two maps correspond to a request and response (in that order). The request tells us what request to expect and the response map describes the response.

Another example:

(fact "User history is posted to scrobbling"
       (rest-driven
           [{:method :POST :url "/events"
             :body [(Pattern/compile "\\{.*\"userid\":\"userid\".*\\}")
                    "application/json"]}
            {:type :JSON :status 202}]

           (let [response (client/post ...snip...)]

             response => (contains {:status 202}))))

Each pair may be enclosed in a vector if you like:

(fact "Expectations as nested vectors"
       (rest-driven
           [[{:method :GET :url "/events"} {:type :JSON :status 200}]
            [{:method :GET :url "/events"} {:type :JSON :status 201}]]

             (client/get url) => (contains {:status 200})
             (client/get url) => (contains {:status 201})))

You can also specific a map as the body of the request, thereby asserting that the right content is sent:

(fact "I want to know my code is sending out the right information"
       (rest-driven
           [{:method :POST :url "/downstream"
             :body {:information "yes,please"}
            {:type :JSON :status 202}]

           (let [response (client/post {:body (json-str {:infomation "yes,please"}) :content-type :json]

             response => (contains {:status 202}))))

The body can also be a regex or a string along with a content type, specified as a two-valued vector:

        :body ["a string" "text/plain"]
        
        :body [#"a regex" "someothercontent/type"]

The body can also be a predicate, or a two-valued vector with predicate and content-type. If the content-type is not set or set to "application/json" the body will be coerced into clojure format and then applied to the predicate.

        :body [#(= "a string" %) "text/plain"]
        
        :body :foo

If you need to inspect the details of a request you can create a string-capture and analyse the details later:

(fact "I want to capture the body of a request for further inspection"
      (let [capturer (string-capture)]
        (rest-driven [{:method :POST :url resource-path
                       :body ["somethingstrange" "text/plain"]
                       :capture capturer}
                      {:status 204}]
                     (post url {:content-type "text/plain"
                                :body "somethingstrange"
                                :throw-exceptions false}) => (contains {:status 204})
                     (capturer) => "somethingstrange")))

There is also some sweetening of response definitions, like so:

(rest-driven [{:method :GET :url resource-path}
                      {:body {:inigo "montoya"}}]
                     (let [resp (http/get url)]
                       resp => (contains {:status 200})
                       (:headers resp) => (contains {"content-type" "application/json"})
                       (json/read-str (:body resp) :key-fn keyword) => {:inigo "montoya"}))

Request map params:

:method  -> :GET :POST :PUT :DELETE :TRACE :HEAD :OPTIONS or a more unusual method as a string,
            for example "PATCH", "PROPFIND" (defaults to :GET if not supplied)
:params  -> a map of expected request params in the form {"name" "value"} or {:name "value"}
            that would match ?name=value
            alternatively use :any to match any params
:body    -> a map that should match the body of the request or a predicate or a vector containing 
            a string/predicate/regex plus the content type.
:url     -> a string or regex that should match the url
:headers -> a map of headers that are expected on the incoming request where
            keys are header names and values are header values.
:capture -> an instance created using the string-capture function which captures the body
            of the request as a string for later inspection.
:and     -> a function that will receive a ClientDriverRequest and can apply
            additional rest-driver setup steps that aren't explicitly supported
            by rest-cljer.
:not     -> a map of request params that will NOT appear in the request. Currently
            only :headers is supported (i.e. to match against a header NOT appearing in the request).
            :headers should be specified as a vector of strings, although a deprecated approach is
            to specify a map where keys are header names and values are header values (which can be 
            any value).

Response map params:

:type    -> :JSON (application/json) :XML (text/xml) :PLAIN (text/plain) or any other
            string representing a valid media type (e.g. text/html)
:status  -> the response status as a number
:body    -> the response body as string, byte array or input stream
:headers -> a map of headers that will be added to the response (where key is
            header name and value is header value).
:and     -> a function that will receive a ClientDriverResponse and can apply
            additional rest-driver setup steps that aren't explicitly supported
            by rest-cljer.
:times   -> for repeating responses, the number of times a matching request will
            be given this response (use :times :any to use this response for an
            unlimited number of matching requests).
:after   -> return respone after a sepecified number of milliseconds 
            (e.g. :after 1000 will return call after 1 second).

License

Distributed under the Eclipse Public License, the same as Clojure.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].