我是Scala新手,我正在用Spray.io移动我的第一步。我已经定义了一堆路由,当我通过Curl手动运行它们时似乎工作得很好。但是,当我尝试对' GET / documents进行单元测试时,我确实遇到了令人讨厌的NullPointerException?q ='使用spray.testkit.Specs2RouteTest
路线。
这是路线定义:
trait MyService extends HttpService {
import DocumentJsonProtocol._
val searchService: SearchService
val myRoute =
path("documents") {
post {
entity(as[Document]) { doc =>
detach() {
val docId = searchService.indexDocument(doc)
complete(201, s"document created: $docId")
}
}
} ~
get {
parameter('q) { q =>
detach() {
val docs = searchService.matchingQuery(q)
complete(docs)
}
}
}
} ~
path("documents" / Segment ) { docId =>
get {
detach() {
searchService.getDocument(docId) match {
case Some(doc) => {
complete(doc)
}
case None => {
complete(404, s"Cannot find a document with id: $docId")
}
}
}
}
}
}
这是失败的测试:
package example.com
import org.specs2.mutable.Specification
import org.specs2.specification.Scope
import org.specs2.mock._
import spray.testkit.Specs2RouteTest
import spray.http._
import spray.httpx.marshalling._
import StatusCodes._
import com.example.services.SearchService
import com.example.data._
import DocumentJsonProtocol._
class MyServiceSpec extends Specification
with Specs2RouteTest
with Mockito
with MyService {
val searchService = mock[SearchService]
def actorRefFactory = system
trait testDoc extends Scope {
val docId = "test-id"
val testDoc =
Document(Some(docId), "test-title", "test-author", "body", None)
searchService.indexDocument(testDoc).returns(docId)
searchService.matchingQuery("test-title").returns(List(testDoc))
}
"MyService" should {
"allows to search documents by keyword" in new testDoc {
Get("/documents?q=hello-test") ~> myRoute ~> check {
Right(entity) === marshal(List(testDoc))
}
}
此操作失败,并显示以下错误:
[ERROR] [04/07/2014 23:56:50.689] [io-composable-MyServiceSpec-akka.actor.default-dispatcher-3] [ActorSystem(io-composable-MyServiceSpec)] Error during processing of request HttpRequest(GET,http://ex
ample.com/documents?q=hello-test,List(),Empty,HTTP/1.1)
java.lang.NullPointerException
at spray.json.CollectionFormats$$anon$1.write(CollectionFormats.scala:26)
at spray.json.CollectionFormats$$anon$1.write(CollectionFormats.scala:25)
at spray.httpx.SprayJsonSupport$$anonfun$sprayJsonMarshaller$1.apply(SprayJsonSupport.scala:43)
at spray.httpx.SprayJsonSupport$$anonfun$sprayJsonMarshaller$1.apply(SprayJsonSupport.scala:42)
at spray.httpx.marshalling.Marshaller$MarshallerDelegation$$anonfun$apply$1.apply(Marshaller.scala:58)
at spray.httpx.marshalling.Marshaller$MarshallerDelegation$$anonfun$apply$1.apply(Marshaller.scala:58)
at spray.httpx.marshalling.Marshaller$MarshallerDelegation$$anonfun$apply$2.apply(Marshaller.scala:61)
at spray.httpx.marshalling.Marshaller$MarshallerDelegation$$anonfun$apply$2.apply(Marshaller.scala:60)
at spray.httpx.marshalling.Marshaller$$anon$2.apply(Marshaller.scala:47)
at spray.httpx.marshalling.BasicToResponseMarshallers$$anon$1.apply(BasicToResponseMarshallers.scala:35)
at spray.httpx.marshalling.BasicToResponseMarshallers$$anon$1.apply(BasicToResponseMarshallers.scala:22)
at spray.httpx.marshalling.ToResponseMarshaller$$anonfun$compose$1.apply(Marshaller.scala:69)
at spray.httpx.marshalling.ToResponseMarshaller$$anonfun$compose$1.apply(Marshaller.scala:69)
at spray.httpx.marshalling.ToResponseMarshaller$$anon$3.apply(Marshaller.scala:81)
at spray.httpx.marshalling.ToResponseMarshallable$$anon$6.marshal(Marshaller.scala:141)
at spray.httpx.marshalling.ToResponseMarshallable$$anon$7.apply(Marshaller.scala:145)
at spray.httpx.marshalling.ToResponseMarshallable$$anon$7.apply(Marshaller.scala:144)
at spray.routing.RequestContext.complete(RequestContext.scala:235)
答案 0 :(得分:1)
我在阅读您的代码后可以看到的问题是您使用“test-title”参数模拟matchingQuery
函数并使用“hello-test”发出请求查询参数,导致mock返回null。