播放框架检查密钥是否存在
Play framework check whether a key exists
我使用 Play Framework 来简化 JSON 在 Scala 中的解析。我的代码如下所示:
def getAuthToken(userid: String, password: String): String = {
val body: JsValue = Json.obj("userid" -> userid , "password" -> password)
val res = Json.parse(Http("https://<some url>")
.postData(body.toString()).asString.body)
res("token").toString()
}
现在,如果我提供正确的用户 ID 和密码,我肯定会在我的 res
对象中得到一个 token
。所以我正在用 Scala 编写一个测试用例,目前看起来像这样,我没有传递有效的用户名和密码:
class ApiCheckerTest extends FunSuite {
test("ApiChecker.getAuthToken") {
assert(ApiChecker.getAuthToken("" , "") == null)
}
}
当我尝试 运行 时,出现了这个异常:
token
java.util.NoSuchElementException: token
at play.api.libs.json.JsLookup$.apply$extension1(JsLookup.scala:68)
at ApiChecker$.getAuthToken(ApiChecker.scala:15)
at ApiCheckerTest$$anonfun.apply(ApiCheckerTest.scala:5)
at ApiCheckerTest$$anonfun.apply(ApiCheckerTest.scala:5)
at org.scalatest.OutcomeOf$class.outcomeOf(OutcomeOf.scala:85)
at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
at org.scalatest.Transformer.apply(Transformer.scala:22)
at org.scalatest.Transformer.apply(Transformer.scala:20)
at org.scalatest.FunSuiteLike$$anon.apply(FunSuiteLike.scala:186)
at org.scalatest.TestSuite$class.withFixture(TestSuite.scala:196)
at org.scalatest.FunSuite.withFixture(FunSuite.scala:1560)
at org.scalatest.FunSuiteLike$class.invokeWithFixture(FunSuiteLike.scala:183)
...
ApiChecker$.getAuthToken(ApiChecker.scala:15)
是 getAuthToken
函数的最后一行。
如何测试 token
是否出现在 res
中?
res("token")
等同于 res.apply("token")
您有一个 res
类型 JsValue
。 JsValue
有一个应用方法,它接受一个 String
和 return 以及另一个 JsValue
。现在这个apply方法的问题是它也会抛出异常,这里看看这个方法
/**
* Access a value of this array.
*
* @param fieldName Element index.
*/
def apply(fieldName: String): JsValue = result match {
case JsDefined(x) => x match {
case arr: JsObject => arr.value.lift(fieldName) match {
case Some(x) => x
case None => throw new NoSuchElementException(String.valueOf(fieldName))
}
case _ =>
throw new Exception(x + " is not a JsObject")
}
case x: JsUndefined =>
throw new Exception(String.valueOf(x.error))
}
但是你写的函数,只有 return 有一个字符串,让异常冒出来。
def getAuthToken(userid: String, password: String): String
所以有两种方法可以继续,要么您更改 return 类型以同时指示您的函数可能会出错
def getAuthToken(userid: String, password: String): Try[String] = {
val body: JsValue = Json.obj("userid" -> userid , "password" -> password)
val res = Json.parse(Http("https://<some url>")
.postData(body.toString()).asString.body)
Try(res("token").toString())
}
或者,保持相同的设置并仅在 try catch 块内调用您的方法。
我会说使用 Try[String]
return 类型,或者如果您只关心令牌是否存在,请使用 Option[String]
return 类型。这是一个示例
def getAuthToken(userid: String, password: String): Option[String] = {
val body: JsValue = Json.obj("userid" -> userid , "password" -> password)
val res = Json.parse(Http("https://<some url>")
.postData(body.toString()).asString.body)
Try(res("token").toString()).toOption
}
这使您的代码更安全且更易于测试,现在您只需检查结果是 None
而不是 Some(token)
。
我使用 Play Framework 来简化 JSON 在 Scala 中的解析。我的代码如下所示:
def getAuthToken(userid: String, password: String): String = {
val body: JsValue = Json.obj("userid" -> userid , "password" -> password)
val res = Json.parse(Http("https://<some url>")
.postData(body.toString()).asString.body)
res("token").toString()
}
现在,如果我提供正确的用户 ID 和密码,我肯定会在我的 res
对象中得到一个 token
。所以我正在用 Scala 编写一个测试用例,目前看起来像这样,我没有传递有效的用户名和密码:
class ApiCheckerTest extends FunSuite {
test("ApiChecker.getAuthToken") {
assert(ApiChecker.getAuthToken("" , "") == null)
}
}
当我尝试 运行 时,出现了这个异常:
token
java.util.NoSuchElementException: token
at play.api.libs.json.JsLookup$.apply$extension1(JsLookup.scala:68)
at ApiChecker$.getAuthToken(ApiChecker.scala:15)
at ApiCheckerTest$$anonfun.apply(ApiCheckerTest.scala:5)
at ApiCheckerTest$$anonfun.apply(ApiCheckerTest.scala:5)
at org.scalatest.OutcomeOf$class.outcomeOf(OutcomeOf.scala:85)
at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
at org.scalatest.Transformer.apply(Transformer.scala:22)
at org.scalatest.Transformer.apply(Transformer.scala:20)
at org.scalatest.FunSuiteLike$$anon.apply(FunSuiteLike.scala:186)
at org.scalatest.TestSuite$class.withFixture(TestSuite.scala:196)
at org.scalatest.FunSuite.withFixture(FunSuite.scala:1560)
at org.scalatest.FunSuiteLike$class.invokeWithFixture(FunSuiteLike.scala:183)
...
ApiChecker$.getAuthToken(ApiChecker.scala:15)
是 getAuthToken
函数的最后一行。
如何测试 token
是否出现在 res
中?
res("token")
等同于 res.apply("token")
您有一个 res
类型 JsValue
。 JsValue
有一个应用方法,它接受一个 String
和 return 以及另一个 JsValue
。现在这个apply方法的问题是它也会抛出异常,这里看看这个方法
/**
* Access a value of this array.
*
* @param fieldName Element index.
*/
def apply(fieldName: String): JsValue = result match {
case JsDefined(x) => x match {
case arr: JsObject => arr.value.lift(fieldName) match {
case Some(x) => x
case None => throw new NoSuchElementException(String.valueOf(fieldName))
}
case _ =>
throw new Exception(x + " is not a JsObject")
}
case x: JsUndefined =>
throw new Exception(String.valueOf(x.error))
}
但是你写的函数,只有 return 有一个字符串,让异常冒出来。
def getAuthToken(userid: String, password: String): String
所以有两种方法可以继续,要么您更改 return 类型以同时指示您的函数可能会出错
def getAuthToken(userid: String, password: String): Try[String] = {
val body: JsValue = Json.obj("userid" -> userid , "password" -> password)
val res = Json.parse(Http("https://<some url>")
.postData(body.toString()).asString.body)
Try(res("token").toString())
}
或者,保持相同的设置并仅在 try catch 块内调用您的方法。
我会说使用 Try[String]
return 类型,或者如果您只关心令牌是否存在,请使用 Option[String]
return 类型。这是一个示例
def getAuthToken(userid: String, password: String): Option[String] = {
val body: JsValue = Json.obj("userid" -> userid , "password" -> password)
val res = Json.parse(Http("https://<some url>")
.postData(body.toString()).asString.body)
Try(res("token").toString()).toOption
}
这使您的代码更安全且更易于测试,现在您只需检查结果是 None
而不是 Some(token)
。