【发布时间】:2017-05-06 19:33:15
【问题描述】:
我想知道是否存在编写通用单元测试代码的已知模式,其目的是检查(作为黑盒)类型类的各种实例(实现)。例如:
import Test.HUnit
class M a where
foo :: a -> String
cons :: Int -> a -- some constructor
data A = A Int
data B = B Int
instance M A where
foo _ = "foo"
cons = A
instance M B where
foo _ = "bar" -- implementation error
cons = B
我想编写一个函数tests 返回一个Test,并以某种方式指定tests 应用代码的特定实例。我正在考虑将tests添加到具有默认实现的类的定义中(暂时忽略测试代码和实际代码之间的耦合问题),但我不能简单地拥有tests :: Test,即使我尝试@987654327 @ (因此必须人为地传递给定类型的具体元素来调用函数),我无法弄清楚如何在代码中引用 cons 和 foo(类型注释像 (cons 0) :: a 不会这样做) .
假设我有class (Eq a) => M a where ...,而类型A 和B 派生Eq,我可以用类似的东西欺骗编译器(添加到M 的定义中):
tests :: a -> Test
tests x = let
y = (cons 0)
z = (x == y) -- compiler now knows y :: a
in
TestCase (assertEqual "foo" (foo y) "foo")
main = do
runTestTT $ TestList
[ tests (A 0)
, tests (B 0)
]
但这一切对我来说都很丑陋。任何建议都热烈欢迎
【问题讨论】: