1

I am fairly new to spray . I am trying to get the testing correctly so I used the example shown in spary testkit however I am getting this errors. any assistance will greatly appreciated :

The service should

Could not initialize class spray.http.Uri$
java.lang.NoClassDefFoundError: Could not initialize class spray.http.Uri$
    at spray.httpx.RequestBuilding$RequestBuilder.apply(RequestBuilding.scala:36)
    at spray.httpx.RequestBuilding$RequestBuilder.apply(RequestBuilding.scala:34)
    at com.tr.route.EventRouteTester$$anonfun$3$$anonfun$apply$2.apply(EventRouteTester.scala:38)
    at com.tr.route.EventRouteTester$$anonfun$3$$anonfun$apply$2.apply(EventRouteTester.scala:38)

return a 'PONG!' response for GET requests to /ping

Could not initialize class spray.http.Uri$
java.lang.NoClassDefFoundError: Could not initialize class spray.http.Uri$
    at spray.httpx.RequestBuilding$RequestBuilder.apply(RequestBuilding.scala:36)
    at spray.httpx.RequestBuilding$RequestBuilder.apply(RequestBuilding.scala:34)
    at com.tr.route.EventRouteTester$$anonfun$3$$anonfun$apply$6.apply(EventRouteTester.scala:44)
    at com.tr.route.EventRouteTester$$anonfun$3$$anonfun$apply$6.apply(EventRouteTester.scala:44)

leave GET requests to other paths unhandled

scala/collection/GenTraversableOnce$class
java.lang.NoClassDefFoundError: scala/collection/GenTraversableOnce$class
    at spray.http.Uri$Query.<init>(Uri.scala:496)
    at spray.http.Uri$Query$Empty$.<init>(Uri.scala:575)
    at spray.http.Uri$Query$Empty$.<clinit>(Uri.scala)
    at spray.http.parser.UriParser.<init>(UriParser.scala:37)
    at spray.http.Uri$.apply(Uri.scala:231)
    at spray.http.Uri$.apply(Uri.scala:203)
    at spray.http.Uri$.<init>(Uri.scala:194)
    at spray.http.Uri$.<clinit>(Uri.scala)
    at spray.httpx.RequestBuilding$RequestBuilder.apply(RequestBuilding.scala:36)
    at spray.httpx.RequestBuilding$RequestBuilder.apply(RequestBuilding.scala:34)
    at spray.httpx.RequestBuilding$RequestBuilder.apply(RequestBuilding.scala:33)
    at com.tr.route.EventRouteTester$$anonfun$3$$anonfun$apply$9.apply(EventRouteTester.scala:50)
    at com.tr.route.EventRouteTester$$anonfun$3$$anonfun$apply$9.apply(EventRouteTester.scala:50)
Caused by: java.lang.ClassNotFoundException: scala.collection.GenTraversableOnce$class
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    ... 13 more

return a MethodNotAllowed error for PUT requests to the root path

this is the test class

class RouteTester extends Specification with Specs2RouteTest with HttpService {
  def actorRefFactory = system // connect the DSL to the test ActorSystem

  val smallRoute =
    get {
      pathSingleSlash {
        complete {
          <html>
            <body>
              <h1>Say hello to <i>spray</i>!</h1>
            </body>
          </html>
        }
      } ~
        path("ping") {
          complete("PONG!")
        }
    }

  "The service" should {

    "return a greeting for GET requests to the root path" in {
      Get() ~> smallRoute ~> check {
        responseAs[String] must contain("Say hello")
      }
    }

    "return a 'PONG!' response for GET requests to /ping" in {
      Get("/ping") ~> smallRoute ~> check {
        responseAs[String] === "PONG!"
      }
    }

    "leave GET requests to other paths unhandled" in {
      Get("/kermit") ~> smallRoute ~> check {
        handled must beFalse
      }
    }

    "return a MethodNotAllowed error for PUT requests to the root path" in {
      Put() ~> sealRoute(smallRoute) ~> check {
        status === MethodNotAllowed
        responseAs[String] === "HTTP method not allowed, supported methods: GET"
      }
    }
  }
}

I am using maven this are the dependencies and versions

  <scala.version>2.11.2</scala.version>
        <spray.version>1.3.1</spray.version>
        <akka.version>2.3.8</akka.version>

      <dependency>
            <groupId>io.spray</groupId>
            <artifactId>spray-can</artifactId>
            <version>${spray.version}</version>
        </dependency>
        <dependency>
            <groupId>io.spray</groupId>
            <artifactId>spray-routing</artifactId>
            <version>${spray.version}</version>
        </dependency>
        <dependency>
            <groupId>io.spray</groupId>
            <artifactId>spray-json_2.11</artifactId>
            <version>${spray.version}</version>
        </dependency>
         <dependency>
            <groupId>io.spray</groupId>
            <artifactId>spray-testkit_2.11</artifactId>
             <version>${spray.version}</version>
        </dependency>
igx
  • 4,101
  • 11
  • 43
  • 88
  • It seems that the code was ran although it should not have been compiled. What is the output of `mvn compile`? – mirelon Mar 05 '15 at 20:03
  • @mirelon mvn clean compile results - build success – igx Mar 05 '15 at 20:24
  • I have no idea why the classes are not found, but I have recently came through this and ended up using pure akka-testkit, testing message passing of the HttpServiceActor (sent HttpRequest and expected HttpResponse). If you are interested I can share some code... – mirelon Mar 05 '15 at 20:36
  • @mirelon sure , that will be awesome . thanks ! – igx Mar 05 '15 at 20:45
  • Maybe it still won't work for you... but you can give it a try. It seems that your real problem are the dependencies (maven downloads them to a local repository and then when it runs the test, it cannot find the classes) - check your local maven repo if it contains the dependencies – mirelon Mar 05 '15 at 20:55

2 Answers2

1

Recently I was too struggling with various testkits and ended up using pure Akka TestKit, because Spray TestKit was forcing me to split my HttpServiceActors into separate traits and actors, which was not acceptable for me.

I can share some code for an inspiration, you can give it a try (unless someone come with a better answer):

RestInterface.scala:

import spray.routing.HttpServiceActor

class RestInterface extends HttpServiceActor {
  override def receive: Receive = runRoute(smallRoute)
  val smallRoute =
    get {
      pathSingleSlash {
        complete {
          <html>
            <body>
              <h1>Say hello to <i>spray</i>!</h1>
            </body>
          </html>
        }
      } ~
      path("ping") {
        complete("PONG!")
      }
    }
}

RestInterfaceSpec.scala:

import akka.actor.{Props, ActorSystem}
import akka.testkit.{TestActorRef, ImplicitSender, TestKit}
import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpecLike}
import spray.http.HttpResponse
import spray.httpx.RequestBuilding

class RestInterfaceSpec(_system: ActorSystem) extends TestKit(_system) with ImplicitSender with WordSpecLike with Matchers with BeforeAndAfterAll with RequestBuilding with SpecHelper {
  def this() = this(ActorSystem("MySpec"))

  "The service" must {
    "return a response" in {
      val service = TestActorRef[RestInterface]
      service ! Get("/")
      expectMsgType[HttpResponse]
    }
  }
}

SpecHelper.scala:

import akka.actor.ActorSystem
import akka.testkit.TestKit

trait SpecHelper extends BeforeAndAfterAll { this: Suite =>
  implicit val system: ActorSystem

  override def afterAll(): Unit = {
    TestKit.shutdownActorSystem(system)
  }
}
mirelon
  • 4,896
  • 6
  • 40
  • 70
  • Well no luck there either ... running your code and getting this error: A needed class was not found. This could be due to an error in your runpath. Missing class: scala/runtime/AbstractPartialFunction$mcVL$sp java.lang.NoClassDefFoundError: scala/runtime/AbstractPartialFunction$mcVL$sp at java.lang.ClassLoader.defineClass1(Native Method) ... – igx Mar 05 '15 at 21:32
  • It is possible that it will be pure maven issue, take a look at http://stackoverflow.com/questions/16420935/a-required-class-was-missing-while-executing-org-apache-maven-pluginsmaven-sure, http://stackoverflow.com/questions/18442753/a-required-class-was-missing-while-executing-org-apache-maven-pluginsmaven-war, http://stackoverflow.com/questions/20689773/casbah-scala-runtime-error – mirelon Mar 05 '15 at 21:35
  • It doesn't seem like a maven but maybe – igx Mar 06 '15 at 04:59
  • Hi, thanks for the hint you were right, it was a maven issue although more like version of spray modules. Thanks your code did gave me some inspiration and I used your approach. thanks man – igx Mar 09 '15 at 09:07
1

solved ! The problem was the dependencies the require different versions. i.e spray-can and spray-routing artifacts both depend on scala 2.10 while the rest of declared dependencies depend on scala 2.11.

all I had to do is change the dependencies to:

<scalaBinaryVersion>2.11</scalaBinaryVersion>
<dependency>
    <groupId>io.spray</groupId>
    <artifactId>spray-can_${scalaBinaryVersion}</artifactId>

    <version>${spray.version}</version>
</dependency>
<dependency>
    <groupId>io.spray</groupId>
    <artifactId>spray-routing_${scalaBinaryVersion}</artifactId>

    <version>${spray.version}</version>
</dependency>

and problem solved !

igx
  • 4,101
  • 11
  • 43
  • 88
  • Oh yes, I overlooked it. I use SBT instead of Maven and it hides this in double-percent symbol: http://stackoverflow.com/questions/17461453/build-scala-and-symbols-meaning – mirelon Mar 09 '15 at 09:28