a-fistful-of-code / pre-canned

Mocking HTTP services on Akka HTTP for integration testing

GitHub

Pre-canned

Build Status Maven Central

Mocking HTTP services on Akka HTTP for integration testing.

Port of NET-A-PORTER/pre-canned from spray can to Akka HTTP, cross-compiled for Scala 2.11 and 2.12.

Introduction

Pre-canned helps you to mock out the HTTP services your application depends on. This can be especially useful for your integration testing.

For SBT add the dependency "io.github.a-fistful-of-code" %% "pre-canned" % "0.1.2" % "test"

DSLs

Pre-canned currently comes in two flavours:

  • basic - Simple, but many parentheses
  • fancy - Few parentheses, but quite wordy

Help make Pre-canned better and submit a new improved flavour via a PR, or ideas for one in an issue.

There are a basic set of expectations and canned responses. Feel free to contribute more via a PR.

basic

import com.netaporter.precanned.dsl.basic._

val animalApi = httpServerMock(system).bind(8765).block

animalApi.expect(get, path("/animals"), query("name" -> "giraffe"))
  .andRespondWith(resource("/responses/giraffe.json"))
  .blockUpTo(5.seconds)

resource("example.json") will look for files in src/main/resources/example.json or src/test/resources/example.json

fancy

import com.netaporter.precanned.dsl.fancy._

val animalApi = httpServerMock(system).bind(8766).block

animalApi expect
  get and path("/animals") and query("name" -> "giraffe") and
respond using
  resource("/responses/giraffe.json") end()

Adding artificial latency

You can add an artificial latency with delay(). For example, adding a 5 second delay:

basic DSL

import scala.concurrent.duration._

animalApi.expect(get, path("/animals"))
  .andRespondWith(resource("/responses/giraffe.json"), delay(5.seconds))

fancy DSL

import scala.concurrent.duration._

animalApi expect
  get and path("/animals") and
respond using
  resource("/responses/giraffe.json") and delay(5.seconds) end()

Blocking until expectations have been added

Normally, when you use the DSL, expectations are added asynchronously. To block until an expectation is successfully added, use blockUpTo = duration as shown in the examples below. This will return as soon the expectation has been added, or the blockFor has been reached, whichever is sooner.

basic DSL

import scala.concurrent.duration._

animalApi.expect(get, path("/animals"))
  .andRespondWith(resource("/responses/giraffe.json"))
  .blockUpTo(5.seconds)

fancy DSL

By default the fancy DSL blocks up to 3 seconds, however you can change it like so:

import scala.concurrent.duration._

animalApi expect
  get and path("/animals") and
respond using
  resource("/responses/giraffe.json") end(blockUpTo = 5.seconds)

You can disable blocking of adding expectations, like so:

import scala.concurrent.duration._

animalApi expect
  get and path("/animals") and
respond using
  resource("/responses/giraffe.json") end(blockUpTo = Duration.Zero)