更具体地说,我正在寻找一个类型的函数:
f :: site -> SpecM (TestApp site) b -> IO b
或类似的。
换句话说,我正在寻找的反函数:
liftIO :: IO b -> SpecM (TestApp _site) b
我查看了Yesod.Test
文档和源代码并尝试自己构建它,但我似乎在任何地方都找不到它,而且构建起来似乎也不简单。我是否忽略了某些东西,它可能存在于某个地方?还是以我没有考虑过的方式构建起来很简单?
背景
我多次遇到需要这样的功能,但到目前为止,我总是能够解决或不做。但在我最近的情况下,它似乎无法解决:我想编写一个 Monadic QuickCheck 属性,它可以设置一个任意的数据库环境 ( runDB . insert
) 并在其上运行一些处理程序来测试我的应用程序的某些不变量。
这是我尝试的最远距离:
propSpec = do
context "qt" $ do
it "monadic" $ property $ \a b -> monadicIO $ do
run $ withServer $ \site -> yesodSpec site $ runDB $ insert $ User{..}
assert $ a /= b
withServer cont = do
p <- runLogging $ withSqlitePool "database_test.db3" 10 $ \pool -> do
runSqlPool (runMigration migrateAll) pool
return pool
wipeDB (MyApp p)
cont (MyApp p, id)
可以理解的是,这会导致以下类型错误:
/path/to/project/spec/Spec.hs:301:35: error:
• Couldn't match type ‘hspec-core-2.2.4:Test.Hspec.Core.Spec.Monad.SpecM
() ()’
with ‘IO a0’
Expected type: IO a0
Actual type: Spec
• In the expression:
yesodSpec site $ runDB $ insert $ User{..}
In the second argument of ‘($)’, namely
‘\ site
-> yesodSpec site $ runDB $ insert $ User{..}’
In the second argument of ‘($)’, namely
‘withServer
$ \ site
-> yesodSpec site $ runDB $ insert $ User{..}’
/path/to/project/spec/Spec.hs:301:52: error:
• Couldn't match type ‘ST.StateT
(YesodExampleData MyApp) IO (Key User)’
with ‘transformers-0.5.2.0:Control.Monad.Trans.Writer.Lazy.WriterT
[YesodSpecTree (MyApp, a1 -> a1)]
Data.Functor.Identity.Identity
()’
Expected type: YesodSpec (MyApp, a1 -> a1)
Actual type: YesodExample MyApp (Key User)
• In the second argument of ‘($)’, namely
‘runDB $ insert $ User{..}’
In the expression:
yesodSpec site $ runDB $ insert $ User{..}
In the second argument of ‘($)’, namely
‘\ site
-> yesodSpec site $ runDB $ insert $ User{..}’
• Relevant bindings include
site :: (MyApp, a1 -> a1)
(bound at /path/to/project/spec/Spec.hs:301:27)
有任何想法吗?
另外,之前有没有人Test.QuickCheck.Monadic
成功使用过Yesod.Test
?或者,如果可能没有成功,至少尝试过这样做?