带有 Futures 和 Case 类 的 Specs2

Specs2 with Futures and Case Classes

我在使用 Futures 作为使用 Scala 的答案时遇到了很多问题 Dispatch for asynchronous HTTP calls. I also used Case Class Matchers

假设我在这里打电话:http://ip.jsontest.com/ wich returns 这个 json:

{

"ip": "x.xxx.xxx.xxx"

}

所以我构建了我的规范

import dispatch._
import Defaults._

import org.json4s._
import org.json4s.jackson.JsonMethods._
import org.specs2.concurrent.ExecutionEnv
import org.specs2.mutable.Specification


import org.specs2.matcher.MatcherMacros
import scala.language.experimental.macros

import scala.concurrent.duration._



class TestDispatchJSON extends Specification  with MatcherMacros{

  implicit val formats = DefaultFormats

  case class Direction(ip: String)

  val translateAPI = url("http://ip.jsontest.com/")

  val response = Http( translateAPI OK as.String)

  val direction = for(json <- response ) yield parse( json ).extract[Direction]




  "The direction" should {

    "direction must be of class Direction" in { implicit ee: ExecutionEnv =>
      direction must matchA[Direction].ip("x.xxx.xxx.xxx").await(retries = 2, timeout = 10.seconds)
    }




  }


}

但是它不起作用,我得到这个错误。

Testing started at 13:44 ...
13:44:41.170 [New I/O worker #1] DEBUG c.n.h.c.p.n.r.NettyConnectListener - Request using non cached Channel '[id: 0x702a0c8a, /172.16.10.142:5548 => ip.jsontest.com/64.233.184.121:80]':
DefaultHttpRequest(chunked: false)
GET / HTTP/1.1
Connection: keep-alive
Host: ip.jsontest.com
Accept: */*
User-Agent: Dispatch/0.11.3

13:44:41.335 [New I/O worker #1] DEBUG c.n.h.c.p.netty.handler.HttpProtocol - 

Request DefaultHttpRequest(chunked: false)
GET / HTTP/1.1
Connection: keep-alive
Host: ip.jsontest.com
Accept: */*
User-Agent: Dispatch/0.11.3

Response DefaultHttpResponse(chunked: true)
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: application/json; charset=ISO-8859-1
Vary: Accept-Encoding
Date: Thu, 18 Jun 2015 11:44:41 GMT
Server: Google Frontend
Cache-Control: private
Alternate-Protocol: 80:quic,p=0
Accept-Ranges: none
Transfer-Encoding: chunked

13:44:41.337 [New I/O worker #1] DEBUG c.n.h.c.p.n.channel.ChannelManager - Adding key: http://ip.jsontest.com:80 for channel [id: 0x702a0c8a, /172.16.10.142:5548 => ip.jsontest.com/64.233.184.121:80]

No usable value for $outer
Can't find ScalaSig for class java.lang.Object
org.json4s.package$MappingException: No usable value for $outer
Can't find ScalaSig for class java.lang.Object
    at org.json4s.reflect.package$.fail(package.scala:96)
    at org.json4s.Extraction$ClassInstanceBuilder.org$json4s$Extraction$ClassInstanceBuilder$$buildCtorArg(Extraction.scala:462)
    at org.json4s.Extraction$ClassInstanceBuilder$$anonfun.apply(Extraction.scala:482)
    at org.json4s.Extraction$ClassInstanceBuilder$$anonfun.apply(Extraction.scala:482)
    at scala.collection.TraversableLike$$anonfun$map.apply(TraversableLike.scala:245)
    at scala.collection.TraversableLike$$anonfun$map.apply(TraversableLike.scala:245)
    at scala.collection.mutable.ResizableArray$class.foreach(ResizableArray.scala:59)
    at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:48)
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:245)
    at scala.collection.AbstractTraversable.map(Traversable.scala:104)
    at org.json4s.Extraction$ClassInstanceBuilder.org$json4s$Extraction$ClassInstanceBuilder$$instantiate(Extraction.scala:470)
    at org.json4s.Extraction$ClassInstanceBuilder$$anonfun$result.apply(Extraction.scala:515)
    at org.json4s.Extraction$ClassInstanceBuilder$$anonfun$result.apply(Extraction.scala:512)
    at org.json4s.Extraction$.org$json4s$Extraction$$customOrElse(Extraction.scala:524)
    at org.json4s.Extraction$ClassInstanceBuilder.result(Extraction.scala:512)
    at org.json4s.Extraction$.extract(Extraction.scala:351)
    at org.json4s.Extraction$.extract(Extraction.scala:42)
    at org.json4s.ExtractableJsonAstNode.extract(ExtractableJsonAstNode.scala:21)
    at com.elevenpaths.TestDispatchJSON$$anonfun.apply(TestDispatchJSON.scala:35)
    at com.elevenpaths.TestDispatchJSON$$anonfun.apply(TestDispatchJSON.scala:35)
    at scala.util.Success$$anonfun$map.apply(Try.scala:236)
    at scala.util.Try$.apply(Try.scala:191)
    at scala.util.Success.map(Try.scala:236)
    at scala.concurrent.Future$$anonfun$map.apply(Future.scala:235)
    at scala.concurrent.Future$$anonfun$map.apply(Future.scala:235)
    at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
    at scala.concurrent.impl.ExecutionContextImpl$AdaptedForkJoinTask.exec(ExecutionContextImpl.scala:121)
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.pollAndExecAll(ForkJoinPool.java:1253)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1346)
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
Caused by: org.json4s.package$MappingException: Can't find ScalaSig for class java.lang.Object
    at org.json4s.reflect.ScalaSigReader$.findClass(ScalaSigReader.scala:42)
    at org.json4s.reflect.ScalaSigReader$.org$json4s$reflect$ScalaSigReader$$read(ScalaSigReader.scala:36)
    at org.json4s.reflect.ScalaSigReader$.org$json4s$reflect$ScalaSigReader$$read(ScalaSigReader.scala:36)
    at org.json4s.reflect.ScalaSigReader$.readField(ScalaSigReader.scala:38)
    at org.json4s.reflect.Reflector$ClassDescriptorBuilder$$anonfun.apply(Reflector.scala:66)
    at org.json4s.reflect.Reflector$ClassDescriptorBuilder$$anonfun.apply(Reflector.scala:65)
    at scala.collection.TraversableLike$$anonfun$map.apply(TraversableLike.scala:245)
    at scala.collection.TraversableLike$$anonfun$map.apply(TraversableLike.scala:245)
    at scala.collection.mutable.ResizableArray$class.foreach(ResizableArray.scala:59)
    at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:48)
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:245)
    at scala.collection.AbstractTraversable.map(Traversable.scala:104)
    at org.json4s.reflect.Reflector$ClassDescriptorBuilder.fields(Reflector.scala:65)
    at org.json4s.reflect.Reflector$ClassDescriptorBuilder.fields(Reflector.scala:78)
    at org.json4s.reflect.Reflector$ClassDescriptorBuilder.properties(Reflector.scala:82)
    at org.json4s.reflect.Reflector$ClassDescriptorBuilder.result(Reflector.scala:158)
    at org.json4s.reflect.Reflector$.createDescriptor(Reflector.scala:50)
    at org.json4s.reflect.Reflector$$anonfun$describe.apply(Reflector.scala:44)
    at org.json4s.reflect.Reflector$$anonfun$describe.apply(Reflector.scala:44)
    at org.json4s.reflect.package$Memo.apply(package.scala:39)
    at org.json4s.reflect.Reflector$.describe(Reflector.scala:44)
    at org.json4s.Extraction$.extract(Extraction.scala:349)
    at org.json4s.Extraction$ClassInstanceBuilder.org$json4s$Extraction$ClassInstanceBuilder$$buildCtorArg(Extraction.scala:450)
    ... 30 more

方向应该

进程已完成,退出代码为 0

我也想要一个在 Specs2 中使用 futures 的好方法,因为我不喜欢 ExecutionEnvironment,请添加导入你的答案

看起来 json 解析本身不起作用。 No usable value for $outer 消息表明反射可能不适用于 Direction 作为规范的内部 class。所以你应该把它移到外面作为顶级 class.