2013-05-16 5 views
15

У меня есть простой клиент спрей:Как издеваются ответ спрей-клиент

val pipeline = sendReceive ~> unmarshal[GoogleApiResult[Elevation]] 

val responseFuture = pipeline {Get("http://maps.googleapis.com/maps/api/elevation/jsonlocations=27.988056,86.925278&sensor=false") } 

responseFuture onComplete { 
    case Success(GoogleApiResult(_, Elevation(_, elevation) :: _)) => 
    log.info("The elevation of Mt. Everest is: {} m", elevation) 
    shutdown() 

    case Failure(error) => 
    log.error(error, "Couldn't get elevation") 
    shutdown() 
} 

Полный код можно найти here.

Я хочу высмеять ответ сервера для проверки логики в случаях Success и Failure. Единственная соответствующая информация, которую я нашел, была here, но я не смог использовать шаблон торта, чтобы высмеять метод sendReceive.

Любое предложение или пример были бы весьма признательны.

ответ

19

Вот пример одного способа издеваться над ним, используя specs2 для спецификации теста и mockito для насмешки. Во-первых, Main объект переработан в установке класса для насмешливо:

class ElevationClient{ 
    // we need an ActorSystem to host our application in 
    implicit val system = ActorSystem("simple-spray-client") 
    import system.dispatcher // execution context for futures below 
    val log = Logging(system, getClass) 

    log.info("Requesting the elevation of Mt. Everest from Googles Elevation API...") 

    import ElevationJsonProtocol._ 
    import SprayJsonSupport._ 

    def sendAndReceive = sendReceive 

    def elavation = { 
    val pipeline = sendAndReceive ~> unmarshal[GoogleApiResult[Elevation]] 

    pipeline { 
     Get("http://maps.googleapis.com/maps/api/elevation/json?locations=27.988056,86.925278&sensor=false") 
    } 
    } 


    def shutdown(): Unit = { 
    IO(Http).ask(Http.CloseAll)(1.second).await 
    system.shutdown() 
    } 
} 

Затем испытание спецификации:

class ElevationClientSpec extends Specification with Mockito{ 

    val mockResponse = mock[HttpResponse] 
    val mockStatus = mock[StatusCode] 
    mockResponse.status returns mockStatus 
    mockStatus.isSuccess returns true 

    val json = """ 
    { 
     "results" : [ 
      { 
      "elevation" : 8815.71582031250, 
      "location" : { 
       "lat" : 27.9880560, 
       "lng" : 86.92527800000001 
      }, 
      "resolution" : 152.7032318115234 
      } 
     ], 
     "status" : "OK" 
    }  
    """ 

    val body = HttpEntity(ContentType.`application/json`, json.getBytes()) 
    mockResponse.entity returns body 

    val client = new ElevationClient{ 
    override def sendAndReceive = { 
     (req:HttpRequest) => Promise.successful(mockResponse).future 
    } 
    } 

    "A request to get an elevation" should{ 
    "return an elevation result" in { 
     val fut = client.elavation 
     val el = Await.result(fut, Duration(2, TimeUnit.SECONDS)) 
     val expected = GoogleApiResult("OK",List(Elevation(Location(27.988056,86.925278),8815.7158203125))) 
     el mustEqual expected 
    } 
    } 
} 

Так что мой подход здесь должен был первым определить переопределение функции в ElevationClient под названием sendAndReceive что просто делегаты для распыления sendReceive функция. Затем, в спецификации теста, я переопределяю функцию sendAndReceive, чтобы вернуть функцию, которая возвращает завершенный Future, обертывающий макет HttpResponse. Это один из способов сделать то, что вы хотите сделать. Надеюсь, это поможет.

+0

Именно то, что я искал. Спасибо! – Eleni

+2

Мы могли бы просто использовать 'Future.successful (mockResponse)' вместо 'Promise.successful (mockResponse) .future'. Я также предпочел бы сделать 'sendAndReceive' аргумент' ElevationClient' вместо использования переопределения. Затем мы передадим макет 'Function2 [HttpRequest, Future [HttpResponse]]' для нашего 'sendAndReceive'. – Alden

11

Там нет необходимости вводить издевается в этом случае, как вы можете просто построить HttpResponse гораздо проще, используя существующий API:

val mockResponse = HttpResponse(StatusCodes.OK, HttpEntity(ContentTypes.`application/json`, json.getBytes)) 

(Извините за размещение этого в качестве другого ответа, но не имеют достаточно кармы для комментариев)

Смежные вопросы