aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authoradamw <adam@warski.org>2017-10-09 17:03:44 +0200
committeradamw <adam@warski.org>2017-10-09 17:03:44 +0200
commit5620043c1fc9fc846fa4a5fe91b2af7fb1ff6008 (patch)
tree6cc71430df59ad68815352be26696b835e3354ac /core
parente093ee494d45350818933049c498ec5eb4fb98be (diff)
downloadsttp-5620043c1fc9fc846fa4a5fe91b2af7fb1ff6008.tar.gz
sttp-5620043c1fc9fc846fa4a5fe91b2af7fb1ff6008.tar.bz2
sttp-5620043c1fc9fc846fa4a5fe91b2af7fb1ff6008.zip
Backend stubs with fallback (thx to @gabro)
Diffstat (limited to 'core')
-rw-r--r--core/src/main/scala/com/softwaremill/sttp/testing/SttpBackendStub.scala39
-rw-r--r--core/src/test/scala/com/softwaremill/sttp/testing/SttpBackendStubTests.scala21
2 files changed, 49 insertions, 11 deletions
diff --git a/core/src/main/scala/com/softwaremill/sttp/testing/SttpBackendStub.scala b/core/src/main/scala/com/softwaremill/sttp/testing/SttpBackendStub.scala
index 5724264..aa04ef3 100644
--- a/core/src/main/scala/com/softwaremill/sttp/testing/SttpBackendStub.scala
+++ b/core/src/main/scala/com/softwaremill/sttp/testing/SttpBackendStub.scala
@@ -19,7 +19,8 @@ import scala.language.higherKinds
* a response is specified with the incorrect body type.
*/
class SttpBackendStub[R[_], S] private (rm: MonadError[R],
- matchers: Vector[Matcher[_]])
+ matchers: Vector[Matcher[_]],
+ fallback: Option[SttpBackend[R, S]])
extends SttpBackend[R, S] {
/**
@@ -31,15 +32,22 @@ class SttpBackendStub[R[_], S] private (rm: MonadError[R],
new WhenRequest(p)
override def send[T](request: Request[T, S]): R[Response[T]] = {
- val response = matchers
+ matchers
.collectFirst {
case matcher if matcher(request) => matcher.response
- }
- .getOrElse(DefaultResponse)
-
- rm.unit(response.asInstanceOf[Response[T]])
+ } match {
+ case Some(response) => wrapResponse(response)
+ case None =>
+ fallback match {
+ case None => wrapResponse(DefaultResponse)
+ case Some(fb) => fb.send(request)
+ }
+ }
}
+ private def wrapResponse[T](r: Response[_]): R[Response[T]] =
+ rm.unit(r.asInstanceOf[Response[T]])
+
override def close(): Unit = {}
override def responseMonad: MonadError[R] = rm
@@ -57,7 +65,7 @@ class SttpBackendStub[R[_], S] private (rm: MonadError[R],
def thenRespond[T](body: T): SttpBackendStub[R, S] =
thenRespond(Response[T](Right(body), 200, Nil, Nil))
def thenRespond[T](resp: Response[T]): SttpBackendStub[R, S] =
- new SttpBackendStub(rm, matchers :+ Matcher(p, resp))
+ new SttpBackendStub(rm, matchers :+ Matcher(p, resp), fallback)
}
}
@@ -71,16 +79,27 @@ object SttpBackendStub {
* [[https://stackoverflow.com/questions/46642623/cannot-infer-contravariant-nothing-type-parameter]].
*/
def apply[R[_], S, S2 <: S](c: SttpBackend[R, S]): SttpBackendStub[R, S2] =
- new SttpBackendStub[R, S2](c.responseMonad, Vector.empty)
+ new SttpBackendStub[R, S2](c.responseMonad, Vector.empty, None)
/**
* Create a stub backend using the given response monad (which determines
* how requests are wrapped), and any stream type.
*/
def apply[R[_], S](responseMonad: MonadError[R]): SttpBackendStub[R, S] =
- new SttpBackendStub[R, S](responseMonad, Vector.empty)
+ new SttpBackendStub[R, S](responseMonad, Vector.empty, None)
+
+ /**
+ * Create a stub backend which delegates send requests to the given fallback
+ * backend, if the request doesn't match any of the specified predicates.
+ */
+ def withFallback[R[_], S, S2 <: S](
+ fallback: SttpBackend[R, S]): SttpBackendStub[R, S2] =
+ new SttpBackendStub[R, S2](fallback.responseMonad,
+ Vector.empty,
+ Some(fallback))
- private val DefaultResponse = Response[Nothing](Left(""), 404, Nil, Nil)
+ private val DefaultResponse =
+ Response[Nothing](Left("Not Found"), 404, Nil, Nil)
private case class Matcher[T](p: Request[T, _] => Boolean,
response: Response[T]) {
diff --git a/core/src/test/scala/com/softwaremill/sttp/testing/SttpBackendStubTests.scala b/core/src/test/scala/com/softwaremill/sttp/testing/SttpBackendStubTests.scala
index 538dd35..b80ae76 100644
--- a/core/src/test/scala/com/softwaremill/sttp/testing/SttpBackendStubTests.scala
+++ b/core/src/test/scala/com/softwaremill/sttp/testing/SttpBackendStubTests.scala
@@ -13,7 +13,7 @@ class SttpBackendStubTests extends FlatSpec with Matchers with ScalaFutures {
.whenRequestMatches(_.method == Method.GET)
.thenRespondServerError()
- it should "use the first rule if it matches" in {
+ "backend stub" should "use the first rule if it matches" in {
implicit val b = testingStub
val r = sttp.get(uri"http://example.org/a/b/c").send()
r.is200 should be(true)
@@ -48,4 +48,23 @@ class SttpBackendStubTests extends FlatSpec with Matchers with ScalaFutures {
val r = sttp.post(uri"http://example.org").send()
r.futureValue.code should be(404)
}
+
+ val testingStubWithFallback = SttpBackendStub
+ .withFallback(testingStub)
+ .whenRequestMatches(_.uri.path.startsWith(List("c")))
+ .thenRespond("ok")
+
+ "backend stub with fallback" should "use the stub when response for a request is defined" in {
+ implicit val b = testingStubWithFallback
+
+ val r = sttp.post(uri"http://example.org/c").send()
+ r.body should be(Right("ok"))
+ }
+
+ it should "delegate to the fallback for unhandled requests" in {
+ implicit val b = testingStubWithFallback
+
+ val r = sttp.post(uri"http://example.org/a/b").send()
+ r.is200 should be(true)
+ }
}