我有这个单元测试:
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 试图告诉你的(。