复杂的自定义匹配器
Complex custom Matcher
我正在为 API 中某些 API 调用的 Json 输出编写测试,使用 Scala 上的 Play 编写。在我的测试中,这种模式不断出现,我想对其进行去重。
val response = sut.index()(FakeRequest())
val expected = Json.parse("""{ "channels":[] }""")
status(response) must equalTo(OK)
contentType(response) must beSome.which(_ == "application/json")
contentAsJson(response) mustEqual expected
我的第一个方法是这样的:
def assertSameJson(response: Future[Result], expected: JsValue): Unit = {
status(response) must equalTo(OK)
contentType(response) must beSome.which(_ == "application/json")
contentAsJson(response) mustEqual expected
}
但这一点都不符合习惯。好像我在我的规范中添加了 xUnit 断言
我想要一些导致
的东西
response must beSameJson(expected)
我做到的最接近的事情是
def beSameJson(other:Any) =
be_==(other) ^^ ((t: Future[Result]) => contentAsJson(t)) and
be_==(OK) ^^ ((t: Future[Result]) => status(t))
但这并没有检查内容类型,我觉得它很难阅读。
这个Matcher有没有更好的写法?
我认为没有更好的方法来做到这一点。
^^ 运算符就是为了这个目的而存在的,以便在应用其他匹配器之前转换信息。 and
可用于组合两个以上的匹配器。
所以你唯一能做的就是试着把它写得更干净一点:
def beSameJson(data: String) =
equalTo(OK) ^^ {status(_: Future[Result])}
and beSome.which(_ == "application/json") ^^ {contentType(_: Future[Result])}
and be_==(other) ^^ {contentAsJson(_: Future[Result])}
如果您需要更频繁地分解响应,您可以尝试更通用地执行此操作
object Dummy extends Matcher[Any] {
def apply[S <: Any](s: Expectable[S]) = {
result(true,
s.description + " is ignored",
s.description + " is ignored",
s)
}
}
def beResponseWhere(json: Matcher[JsValue] = Dummy, stat: Matcher[Int] = Dummy, tpe: Matcher[Option[String]] = Dummy) =
stat ^^ {status(_: Future[Result])}
and tpe ^^ {contentType(_: Future[Result])}
and json ^^ {contentAsJson(_: Future[Result])}
}
您可能应该使用更好的参数名称(对于此示例,我试图避免与上下文中的方法发生冲突)并且在可用属性上更加完整。
现在你应该可以这样写了:
response must beResponseWhere(
json = equalTo(expected),
tpe = beSome.which(_ == "application/json"),
stat = equalTo(OK)
)
DummyMatcher 允许您省略一些部分。
我显然没有尝试此代码,因为我没有您的完整设置。我还不得不猜测一些从您的代码片段中不清楚的类型。
我正在为 API 中某些 API 调用的 Json 输出编写测试,使用 Scala 上的 Play 编写。在我的测试中,这种模式不断出现,我想对其进行去重。
val response = sut.index()(FakeRequest())
val expected = Json.parse("""{ "channels":[] }""")
status(response) must equalTo(OK)
contentType(response) must beSome.which(_ == "application/json")
contentAsJson(response) mustEqual expected
我的第一个方法是这样的:
def assertSameJson(response: Future[Result], expected: JsValue): Unit = {
status(response) must equalTo(OK)
contentType(response) must beSome.which(_ == "application/json")
contentAsJson(response) mustEqual expected
}
但这一点都不符合习惯。好像我在我的规范中添加了 xUnit 断言
我想要一些导致
的东西response must beSameJson(expected)
我做到的最接近的事情是
def beSameJson(other:Any) =
be_==(other) ^^ ((t: Future[Result]) => contentAsJson(t)) and
be_==(OK) ^^ ((t: Future[Result]) => status(t))
但这并没有检查内容类型,我觉得它很难阅读。 这个Matcher有没有更好的写法?
我认为没有更好的方法来做到这一点。
^^ 运算符就是为了这个目的而存在的,以便在应用其他匹配器之前转换信息。 and
可用于组合两个以上的匹配器。
所以你唯一能做的就是试着把它写得更干净一点:
def beSameJson(data: String) =
equalTo(OK) ^^ {status(_: Future[Result])}
and beSome.which(_ == "application/json") ^^ {contentType(_: Future[Result])}
and be_==(other) ^^ {contentAsJson(_: Future[Result])}
如果您需要更频繁地分解响应,您可以尝试更通用地执行此操作
object Dummy extends Matcher[Any] {
def apply[S <: Any](s: Expectable[S]) = {
result(true,
s.description + " is ignored",
s.description + " is ignored",
s)
}
}
def beResponseWhere(json: Matcher[JsValue] = Dummy, stat: Matcher[Int] = Dummy, tpe: Matcher[Option[String]] = Dummy) =
stat ^^ {status(_: Future[Result])}
and tpe ^^ {contentType(_: Future[Result])}
and json ^^ {contentAsJson(_: Future[Result])}
}
您可能应该使用更好的参数名称(对于此示例,我试图避免与上下文中的方法发生冲突)并且在可用属性上更加完整。
现在你应该可以这样写了:
response must beResponseWhere(
json = equalTo(expected),
tpe = beSome.which(_ == "application/json"),
stat = equalTo(OK)
)
DummyMatcher 允许您省略一些部分。 我显然没有尝试此代码,因为我没有您的完整设置。我还不得不猜测一些从您的代码片段中不清楚的类型。