"not a legal formal parameter"



我有这个单元测试:

class MyServiceSpec extends WordSpec
  with Matchers
  with MockitoSugar
  with BeforeAndAfterEach {
  "MyService" must {
    "succeed if my-endpoint succeeds" in {
      Server.withRouter() {
        GET("/my-endpoint") => Action {
          Results.Ok.sendResource("myservice/my-endpoint.txt")
        }
      } { implicit port =>
        WsTestClient.withClient { client =>
          val result = Await.result(
            new RealMyService(client).getFromEndpoint(), 10.seconds)
          result shouldEqual true
        }
      }
    }
  }
}

sbt告诉我:

» sbt test-only MyService
...
[error] /repos/myrepo/test/services/MyServiceSpec.scala:34: not a legal formal parameter.
[error] Note: Tuples cannot be directly destructured in method or function parameters.
[error]       Either create a single parameter accepting the Tuple1,
[error]       or consider a pattern matching anonymous function: `{ case (param1, param1) => ... }
[error]         GET("/my-endpoint") => Action {
[error]            ^
[error] one error found
[error] (test:compileIncremental) Compilation failed
[error] Total time: 3 s, completed Jun 16, 2017 7:27:11 AM

IntelliJ告诉我:

Application does not take parameters: } expected

在线:

GET("/my-endpoint") => Action {

这到底是什么意思?

Server.withRouter()需要一个模式匹配块。像这样:

Server.withRouter() {
  case GET("/my-endpoint") => Action(whatever)
  case GET("/my-other-endpoint") => Action(whatever)
  case POST("/my-other-endpoint") => Action(whatever)
  case other => Action(whatever) // bad request
}

模式匹配只是一个部分函数,例如

whatever.map((i: Int) => i)

whatever.map { case (i: Int) => i }

两者都做同样的事情。然而,最大的区别在于第二个能够使用unapply()方法进行解构,这是模式匹配的全部意义所在。

回到您的案例 - 模式匹配用于匹配GET("/my-endpoint")案例类(使用案例类,您可以免费获得一些好东西,例如自动为您定义unapply(。如果没有模式匹配,您的块就没有意义;这将是一个普通函数,其中左侧需要一个形式参数,例如 (i: Int) => ...(s: String) => ... .拥有GET("/my-endpoint")根本没有意义,它不是一个正式的参数(这就是 SBT 试图告诉你的(。

相关内容

最新更新