2013-05-16 31 views
15

Tôi có một khách hàng phun đơn giản:Làm thế nào để thử phản ứng phun-client

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() 
} 

Full mã có thể được tìm thấy here.

Tôi muốn giả lập phản hồi của máy chủ để kiểm tra logic trong các trường hợp SuccessFailure. Thông tin liên quan duy nhất tôi tìm thấy là here nhưng tôi không thể sử dụng mẫu bánh để thử phương thức sendReceive.

Bất kỳ đề xuất hoặc ví dụ nào sẽ được đánh giá cao.

Trả lời

19

Dưới đây là một ví dụ về một cách để giả mạo nó bằng cách sử dụng thông số kỹ thuật 2 cho thông số thử nghiệm và mockito cho chế nhạo. Thứ nhất, đối tượng Main refactored thành một thiết lập lớp cho chế giễu:

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() 
    } 
} 

Sau đó, spec kiểm tra:

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 
    } 
    } 
} 

Vì vậy, cách tiếp cận của tôi ở đây là để đầu tiên xác định một chức năng Overridable trong ElevationClient gọi sendAndReceive rằng chỉ đại biểu cho chức năng phun sendReceive. Sau đó, trong thông số thử nghiệm, tôi ghi đè hàm sendAndReceive đó để trả về hàm trả về một số Future hoàn thành gói một mẫu HttpResponse. Đây là một cách tiếp cận để làm những gì bạn muốn làm. Tôi hi vọng cái này giúp được.

+0

Chính xác những gì tôi đang tìm kiếm. Cám ơn! – Eleni

+2

Chúng ta chỉ có thể sử dụng 'Future.successful (mockResponse)' thay vì 'Promise.successful (mockResponse) .future'. Tôi cũng sẽ thay 'sendAndReceive' thành đối số' ElevationClient' thay vì sử dụng ghi đè. Sau đó, chúng ta sẽ chuyển qua một mô hình 'Function2 [HttpRequest, Future [HttpResponse]]' cho 'sendAndReceive' của chúng ta. – Alden

11

Không cần giới thiệu chế giễu trong trường hợp này, vì bạn chỉ có thể xây dựng một HttpResponse dễ dàng hơn nhiều bằng cách sử dụng API hiện có:

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

(Xin lỗi vì đã gửi bài này như một câu trả lời, nhưng không có đủ nghiệp để bình luận)

Các vấn đề liên quan