【发布时间】:2020-08-28 00:34:58
【问题描述】:
我正在尝试为我的某些类型创建Arbitrary 实例,以用于QuickCheck 属性测试。我需要随机生成的 UUID,其约束条件是不允许使用全零 (nil) UUID - 即00000000-0000-0000-0000-000000000000。因此,我设置了以下生成器:
nonzeroIdGen :: Gen UUID.UUID
nonzeroIdGen = arbitrary `suchThat` (not . UUID.null)
我在Arbitrary 实例中使用如下:
instance Arbitrary E.EventId where
arbitrary = do
maybeEid <- E.mkEventId <$> nonzeroIdGen
return $ fromJust maybeEid
一般来说,这是不安全的代码;但是对于测试,据说可以保证非零 UUID,我认为 fromJust 没问题。
mkEventId 定义为
mkEventId :: UUID.UUID -> Maybe EventId
mkEventId uid = EventId <$> validateId uid
使用 EventId 围绕 UUID.UUID 的新类型包装器,并且
validateId :: UUID.UUID -> Maybe UUID.UUID
validateId uuid = if UUID.null uuid then Nothing else Just uuid
令我惊讶的是,由于上述代码生成的全零 UUID,我的测试失败了。 mkEventId 中的 trace 显示以下内容:
00000001-0000-0001-0000-000000000001
Just (EventId {getEventId = 00000001-0000-0001-0000-000000000001})
00000000-0000-0000-0000-000000000000
Nothing
Create valid Events. FAILED [1]
第一个生成的 ID 很好,第二个是全零,尽管我的 nonzeroIdGen 生成器来自上面。我错过了什么?
【问题讨论】:
-
mkEventId的类型是什么?我不明白那个表达式是如何检查类型的...... -
@MarkSeemann,感谢您的帮助!我添加了类型签名。
-
试图重现您的代码,
mkEventId不进行类型检查,但如果我将其更改为mkEventId u = EventId <$> validateId u,它会这样做。 -
啊,新手在这里发帖时试图让事情变得毫无意义的错误。
-
从目前对问题的描述来看,我无法判断出了什么问题……看起来还可以。然后,您不会显示失败的测试的定义。如果您发布 minimal working example... 可能会有所帮助
标签: haskell uuid quickcheck