Scala 如何测试akka http路由以处理异常?

Scala 如何测试akka http路由以处理异常?,scala,akka,akka-stream,akka-http,akka-testkit,Scala,Akka,Akka Stream,Akka Http,Akka Testkit,我有一个简单的akka http应用程序,可以将文件分块上传到服务器。它有两个路由,第一个路由打开一个HTML表单来搜索文件,第二个路由将upload按钮链接到将文件分块并上载的逻辑。然后我构建了一个单元测试(也称为Spec)来测试这两条路线。第一个很简单,它只是确定我可以打开网页。但我想测试的第二个问题是: 如果表单上没有文件,我应该在规范上标识异常 如果表单上有文件,我会检查逻辑并测试它是否真的上传了文件 这是我的akka http应用程序: import akka.Done import

我有一个简单的akka http应用程序,可以将文件分块上传到服务器。它有两个路由,第一个路由打开一个HTML表单来搜索文件,第二个路由将upload按钮链接到将文件分块并上载的逻辑。然后我构建了一个单元测试(也称为Spec)来测试这两条路线。第一个很简单,它只是确定我可以打开网页。但我想测试的第二个问题是:

  • 如果表单上没有文件,我应该在规范上标识异常
  • 如果表单上有文件,我会检查逻辑并测试它是否真的上传了文件
  • 这是我的akka http应用程序:

    import akka.Done
    import akka.actor.ActorSystem
    import akka.http.scaladsl.Http
    import akka.http.scaladsl.model.{ContentTypes, HttpEntity, Multipart}
    import akka.http.scaladsl.server.Directives._
    import akka.stream.ThrottleMode
    import akka.stream.scaladsl.{FileIO, Sink, Source}
    import akka.util.ByteString
    
    import java.io.File
    import scala.concurrent.Future
    import scala.concurrent.duration._
    import scala.util.{Failure, Success}
    
    object UploadingFiles {
      implicit val system = ActorSystem("UploadingFiles")
      val NO_OF_MESSAGES = 1
      val filesRoutes = {
        (pathEndOrSingleSlash & get) {
          complete(
            HttpEntity(
              ContentTypes.`text/html(UTF-8)`,
              """
                |<html>
                |  <body>
                |    <form action="http://localhost:8080/upload" method="post" enctype="multipart/form-data">
                |      <input type="file" name="myFile" multiple>
                |      <button type="submit">Upload</button>
                |    </form>
                |  </body>
                |</html>
              """.stripMargin
            )
          )
        } ~ (path("upload") & post & extractLog) { log =>
          // handling uploading files using multipart/form-data
          entity(as[Multipart.FormData]) { formData =>
            // handle file payload
            val partsSource: Source[Multipart.FormData.BodyPart, Any] = formData.parts
            val filePartsSink: Sink[Multipart.FormData.BodyPart, Future[Done]] =
              Sink.foreach[Multipart.FormData.BodyPart] { bodyPart =>
                if (bodyPart.name == "myFile") {
                  // create a file
                  val filename = "download/" + bodyPart.filename.getOrElse("tempFile_" + System.currentTimeMillis())
                  val file = new File(filename)
    
                  log.info(s"writing to file: $filename")
                  val fileContentsSource: Source[ByteString, _] = bodyPart.entity.dataBytes
                  val fileContentsSink: Sink[ByteString, _] = FileIO.toPath(file.toPath)
    
                  val publishRate = NO_OF_MESSAGES / 1
                  // writing the data to the file using akka-stream graph
                  fileContentsSource
                    .throttle(publishRate, 2 seconds, publishRate, ThrottleMode.shaping)
                    .runWith(fileContentsSink)
                }
              }
            val writeOperationFuture = partsSource.runWith(filePartsSink)
            onComplete(writeOperationFuture) {
              case Success(value) => complete("file uploaded =)")
              case Failure(exception) => complete(s"file failed to upload: $exception")
            }
          }
        }
      }
    
      def main(args: Array[String]): Unit = {
        println("access the browser at: localhost:8080")
        Http().newServerAt("localhost", 8080).bindFlow(filesRoutes)
      }
    }
    
    但是,测试套件似乎正在测试异常的全部内容,我想让它对任何类型的异常都通用。以下是错误:

    akka.http.scaladsl.server.UnsupportedRequestContentTypeRejection@bdc8014 did not equal akka.http.scaladsl.server.UnsupportedRequestContentTypeRejection@1f443fae
    ScalaTestFailureLocation: org.github.felipegutierrez.explore.akka.classic.http.server.highlevel.UploadingFilesSpec at (UploadingFilesSpec.scala:30)
    Expected :akka.http.scaladsl.server.UnsupportedRequestContentTypeRejection@1f443fae
    Actual   :akka.http.scaladsl.server.UnsupportedRequestContentTypeRejection@bdc8014
    
    请注意,正如您在路线中所期望的那样,您有以下媒体类型:

    def mediaType = MediaTypes.`multipart/form-data`
    
    从中创建
    ContentTypeRange
    的方法是:

    ContentTypeRange(MediaRange.apply(MediaTypes.`multipart/form-data`))
    
    而且它没有内容类型

    因此,应采取以下措施:

    “无文件的POST请求上载”应{
    中的“返回不正常”{
    Post(“/upload”)~>文件路由~>检查{
    handled should==(false)//这是有效的
    拒绝应==(未支持的请求内容类型拒绝)(
    Set(ContentTypeRange(MediaRange.apply(MediaTypes.`multipart/formdata`)),
    一些(ContentTypes.NoContentType))
    )
    }
    }
    }
    
    ContentTypeRange(MediaRange.apply(MediaTypes.`multipart/form-data`))