使用幺半群进行简单的单元测试
Simple unit testing with monoids
假设我测试一个函数 echo: String => String
,它只是用 specs2
重复输入。
我可以写一些这样的测试:
class EchoSpec extends SpecificationWithJUnit {
"echo should handle ASCII alphanumeric names" in {
echo("abc") must beEqualTo("abc")
}
"echo should handle names with slashes" in {
echo("a/b/c") must beEqualTo("a/b/c")
}
"echo should handle names with dots" in {
echo("a.b.c") must beEqualTo("a.b.c")
}
"echo should handle non-ASCII names" in {
echo("אבג") must beEqualTo("אבג")
}
}
但是我更愿意摆脱样板代码。所以我正在使用 cats
幺半群:
import cats.implicits._
def testEcho(expected: String): String => Option[String] = {str =>
if (str == expected) none else s"$str != expected".some
}
def testEchoes(expected: List[String]): Option[String] =
expected foldMap testEcho map (_.mkString(", "))
"echo should handle all names" {
val expected = List("abc", "a/b/c", "a.b.c", "אבג")
testEcho(expected) must beNone
}
有意义吗?如何improve/simplify呢?
这里真的需要幺半群吗?我可以 git 去掉上面 没有 幺半群的样板代码吗?
List("abc", "a/b/c", "a.b.c", "אבג")
.foreach(s => echo(s) must beEqualTo(s))
你也可以使用 ScalaCheck
class EchoSpec extends SpecificationWithJUnit with ScalaCheck {
"echo should handle all names" >> prop { s: String =>
echo(s) must beEqualTo(s)
}
}
假设我测试一个函数 echo: String => String
,它只是用 specs2
重复输入。
我可以写一些这样的测试:
class EchoSpec extends SpecificationWithJUnit {
"echo should handle ASCII alphanumeric names" in {
echo("abc") must beEqualTo("abc")
}
"echo should handle names with slashes" in {
echo("a/b/c") must beEqualTo("a/b/c")
}
"echo should handle names with dots" in {
echo("a.b.c") must beEqualTo("a.b.c")
}
"echo should handle non-ASCII names" in {
echo("אבג") must beEqualTo("אבג")
}
}
但是我更愿意摆脱样板代码。所以我正在使用 cats
幺半群:
import cats.implicits._
def testEcho(expected: String): String => Option[String] = {str =>
if (str == expected) none else s"$str != expected".some
}
def testEchoes(expected: List[String]): Option[String] =
expected foldMap testEcho map (_.mkString(", "))
"echo should handle all names" {
val expected = List("abc", "a/b/c", "a.b.c", "אבג")
testEcho(expected) must beNone
}
有意义吗?如何improve/simplify呢? 这里真的需要幺半群吗?我可以 git 去掉上面 没有 幺半群的样板代码吗?
List("abc", "a/b/c", "a.b.c", "אבג")
.foreach(s => echo(s) must beEqualTo(s))
你也可以使用 ScalaCheck
class EchoSpec extends SpecificationWithJUnit with ScalaCheck {
"echo should handle all names" >> prop { s: String =>
echo(s) must beEqualTo(s)
}
}