testing - Yesod/Persistent testing with bracket 模式

标签 testing haskell entity persistent yesod

我是 Haskell 的新手,所以我很难理解 Yesod 中使用的所有高级功能,例如 type instancesequality constraints .我正在尝试实现 bracket pattern在 Yesod 的测试框架中以获得设置/拆卸功能。这是我到目前为止所得到的(通过编辑更新):

module FishMother where

import Control.Exception.Lifted

import TestImport
import Database.Persist
import Database.Persist.GenericSql

import Model

insertYellowfinTuna :: OneSpec Connection FishId
insertYellowfinTuna = runDB . insert $ Fish "Yellowfin Tuna"

deleteFish :: FishId -> OneSpec Connection ()
deleteFish = runDB . delete

withYellowfinTuna :: FishId -> OneSpec Connection ()
withYellowfinTuna = bracket insertYellowfinTuna deleteFish

编译错误如下:

tests/FishMother.hs:18:21:
    Couldn't match type `FishId
             -> Control.Monad.Trans.State.Lazy.StateT
                  (Yesod.Test.OneSpecData Connection) IO ()'
          with `Key SqlPersist Fish'
    Expected type: FishId -> OneSpec Connection ()
      Actual type: (FishId
            -> Control.Monad.Trans.State.Lazy.StateT
             (Yesod.Test.OneSpecData Connection) IO ())
           -> Control.Monad.Trans.State.Lazy.StateT
            (Yesod.Test.OneSpecData Connection) IO ()
    In the return type of a call of `bracket'
    In the expression: bracket insertYellowfinTuna deleteFish
    In an equation for `withYellowfinTuna':
    withYellowfinTuna = bracket insertYellowfinTuna deleteFish

我做错了什么?

最佳答案

重读问题后,我认为简单的答案是使用 a lifted bracket ,它将处理所有变压器问题。我也会留下我原来的答案,因为它可能会让您更深入地了解正在发生的事情。


本例中的问题是 liftIO 的使用。让我们看看类型签名:

liftIO :: MonadIO m => IO a -> m a

这意味着您可以执行任意 I/O 操作(例如,从文件中读取)并在任何允许执行 I/O 的 monad 中运行它,例如数据库 monad。但是,您尝试做的实际上是相反的:将数据库 monad 操作作为正常的 I/O 操作来运行。这不能直接完成,因为数据库操作依赖于额外的上下文 - 特别是数据库连接 - IO monad 不提供。

那么如何将数据库操作转换为 IO 操作呢?我们必须展开。展开是 monad 转换器 的常见事件,它可以被认为是层层叠加。提升(如在 liftIO 中)允许您从较低层执行操作并将其移动到较高层。展开一层。由于展开方式取决于特定的转换器,因此每个转换器都有自己的展开函数。

在 Persistent 的情况下,您可以使用 withSqliteConn 或等效的后端,请参阅 Persistent chapter 中的概要了解更多详情。

关于testing - Yesod/Persistent testing with bracket 模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14393117/

相关文章:

haskell - 如何生成固定长度的数字来总结 Haskell 中的给定数字

recursion - 递归自实例化组件[VHDL]

testing - Symfony - 使用 Lime 进行单元测试

testing - Yii2:使用 composer 安装 codeception 和 phpunit 并使用它

haskell - 强制使用幻像类型的不明确实例

asp.net-mvc-4 - MVC5 Entity Framework 数据库首先带有字符串主键

forms - ZF2 Doctrine - 字段集绑定(bind)

javascript - 单击和内容加载完成后如何运行 Protractor 测试?

testing - Protractor "signing in"|| "login"测试

haskell - map haskell中的最小值