在 HSpec 测试中匹配 "any string" in Haskell 记录

Match "any string" in Haskell record in HSpec test

我有一个数据 class Entity 是这样定义的:

data Entity = Entity { id :: String, name :: String }

和一个 returns IO Entity:

的函数
newPersistentEntity :: String -> IO Entity

我想为此写一个 HSpec 测试:

spec :: Spec
spec = describe "newPersistentEntity function" $
       it "returns a new Entity with a generated id and the specified name" $
       newPersistentEntity "myName" `shouldReturn` Entity {id = <any string>, name = "myName"}

问题是id是数据库生成的UUID。我想断言 id 是使测试通过的字符串。

我怎样才能做到这一点?

您可以创建记录,然后使用它的 id 值来创建您要与之比较的记录吗?类似于:

new <- newPersistentEntity "myName"
new `shouldBe` Entity { id = (id new), name = "myName" }

(注意:没有足够的信息来测试这段代码,将其视为某种伪代码)。

附带说明一下,您的代码看起来不像普通的持久性代码,所以我假设您使用的是不同的库。

Entityid 不能是 String,因为静态类型。但是您可能确实想要强制其评估以确保它不是底部。

spec :: Spec
spec = describe "newPersistentEntity function" $
    it "returns a new Entity with a generated id and the specified name" $ do
        x <- newPersistentEntity "myName"
        pure $! id x  -- Force evaluation of the `id` field to ensure that
                      -- the database actually did return a string here
        name x `shouldBe` "myName"

我实际上以不同的方式自己解决了这个问题,我将在此处展示上下文。您可能不应该使用它,因为接受的答案更容易理解且不那么冗长。

spec :: Spec
spec = describe "newPersistentEntity function" $
       it "returns a new Entity with a generated id and the specified name" $
       newPersistentEntity "myName" >>= (`shouldSatisfy` (\case
           Entity {id = _, name = "myName"} -> True
           _ -> False))

但要使其正常工作,您还需要应用 lamda 大小写语言扩展:

{-# LANGUAGE LambdaCase #-}