Lift / Scala:我如何对api的休息响应进行单元测试?

时间:2017-04-28 20:03:08

标签: scala unit-testing lift

我想测试以下rest api对有效和无效请求的响应。对于exaple给出有效请求它应该返回200并且对于无效请求它应该返回400.如何做到这一点?

object API extends RestHelper {
  implicit val timeout:Timeout = new FiniteDuration(200, SECONDS)
  def init() {
    LiftRules.dispatch.append(API)
  }

  serve {
    case "api" :: "xweb" :: "v1" :: "search" ::  z JsonPost request => {
      RestContinuation.async({
        reply => {
          val future = Promise[String].future
          future.map(x => new InMemoryResponse(x.getBytes("UTF-8"), List(), List(), 200))

          future.onSuccess({
            case response: InMemoryResponse => {
              reply(response)
            }
            case _ => {
              reply(new InternalServerErrorResponse())
            }
          })
          future.onFailure({
            case _ => reply(new InternalServerErrorResponse())
          })
        }
      })
    }

    case "api" :: "xweb" :: "v1" :: "search" ::  _ Get _ => {
      new BadResponse()
    }

    case "api" :: "xweb" :: "v1" :: "search" ::  _ Post _ => {
      new BadResponse()
    }
  }
}

我看过this链接,但似乎是在测试S对象和Req对象。还有关于Specs2的this链接;我没有找到关于测试http响应的任何信息。

请指教。 谢谢。

1 个答案:

答案 0 :(得分:0)

注意:如果您在https://groups.google.com/forum/#!forum/liftweb发布到电梯列表,通常您会得到更快的响应。它受到更密切的监控,通常您会在24小时内得到回复。

关于RestHelper的一个非常酷的事情是它重用了Scala抽象。特别是,RestHelper只是(Req)=>()=>Box[LiftResponse]RestHelper的任何实例都是一个函数,它接受Req并生成一个返回Box[LiftResponse]的函数。 }。通过辅助功能的额外间接通常是从您身上抽象出来的,并且由于Lift必须在内部处理请求/响应处理的一些变化。

在测试期间,一旦您有Req(您的第一个链接描述了如何获取),您就可以apply RestHelper

"My API when handling bad requests" should {
  val testUrl = "/api/xweb/v1/search/15"
  val testBody = "Invalid body"

  "my spec" withReqFor(testUrl) withPost(testBody) in { req =>
    API.apply(req)() must beLike { // the second set of parens unwraps the ()=>Box[LiftResponse]
      case Full(response) =>
        code must beAnInstanceOf[BadResponse] 
    }
  }
}

现在我在非恶意回复处理中注意到的一件事是您使用RestContinuation.async。这种机制与其他机制略有不同,因为异步请求必须在容器级别内部检测。如果您点击该代码路径,则apply实际上会抛出ContinuationException。反过来,ContinuationException将带有一个执行实际响应处理的函数。

对于这些情况,我建议最简单的方法是将除RestContinuation设置之外的所有内容拆分成函数,然后测试该函数。你可以 通过捕捉ContinuationException并调用它的内部来测试它,但它并不是特别简单,你只是在测试函数时获得了很多直接生成响应,并让异步包装器在运行时完成它的工作。