unit-testing - 如何编写确保编译失败的 Scala 单元测试?

标签 unit-testing scala

有没有办法编写类似“单元测试”的东西来确保某些代码编译?

我为什么想要这样的东西?有两个原因。

1) 检查我的 API 的类型安全性。我想要一种方法来确保如果有人传递了错误的值,您会收到编译器错误,而不仅仅是运行时错误。显然,我可以运行编译器并检查错误,但在单元测试中对其进行形式化有助于避免回归,也有助于文档编写。

例如,考虑这个测试。有一些注释掉的代码我用来检查类型安全: https://github.com/squito/boxwood/blob/master/core/src/test/scala/com/quantifind/boxwood/EnumUnionTest.scala#L42 (第 42 行和第 48 行 - 在第 34 行,我调用了另一个具有运行时异常的 API,我可以检查该异常)

实际上我花了一段时间才得到正确的类型安全,所以这些检查很重要。现在,如果我去修改底层实现,我就不能只运行我的测试套件——我还必须记住取消注释这些行并检查编译器错误。

2) 测试宏的错误处理。如果宏有一些错误的输入,它应该会导致编译器错误。这里有同样的问题,同样希望将其放入易于运行的测试套件中。

我使用 ScalaTest,但我很高兴这里有一个包含任何单元测试框架的解决方案。

最佳答案

正如我在上面的评论中指出的,Shapeless 2.0 (尚未发布,但目前可作为一个里程碑)基于 Stefan Zeiger 的解决方案,对您正在寻找的功能进行了非常好的实现。我已经在您的项目中添加了一个演示 here (请注意,我必须更新到 Scala 2.10,因为此解决方案使用宏)。它的工作原理如下:

import shapeless.test.illTyped

//this version won't even compile
illTyped("getIdx(C.Ooga)")

//We can have multiple enum unions exist side by side
import Union_B_C._
B.values().foreach {b => Union_B_C.getIdx(b) should be (b.ordinal())}
C.values().foreach {c => Union_B_C.getIdx(c) should be (c.ordinal() + 2)}

//Though A exists in some union type, Union_B_C still doesn't know about it,
// so this won't compile
illTyped("""
  A.values().foreach {a => Union_B_C.getIdx(a) should be (a.ordinal())}
""")

如果我们将第二次调用 illTyped 中的代码更改为可以编译的代码:

B.values().foreach {a => Union_B_C.getIdx(a) should be (a.ordinal())}

我们会收到以下编译错误:

[error] .../EnumUnionTest.scala:56: Type-checking succeeded unexpectedly.
[error] Expected some error.
[error]     illTyped("""
[error]             ^
[error] one error found
[error] (core/test:compile) Compilation failed

如果您希望测试失败,您可以很容易地适应 the implementation in Shapeless 。请参阅Miles's answermy previous question进行一些补充讨论。

关于unit-testing - 如何编写确保编译失败的 Scala 单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20114298/

相关文章:

java - GregorianCalendar 无法添加 97 天?

python - 以编程方式检测是否正在测试 python 代码

PHP - 如何生成带有控制字符或二进制数据的字符串?

scala - Apache Spark EOF 异常

xml - Scala - XML PrettyPrinter.format() 给出 noSuchMethodError

scala - 合并 scalaz-stream 输入进程在 stdin 上似乎为 "wait"

json - Lift Framework无法反序列化JSON数据

unit-testing - NUnit的[TestCaseSource]具有多个参数,例如MbUnit的[Factory]

c# - 如何自动验证我的 View 中的所有控件是否都设置了绑定(bind)?

javascript - 在 Jest 中,如何测试组件中的非模拟方法是否正在单击时运行?