我需要測試很多訪問數據庫的函數(通過Persistent)。雖然我可以使用monadicIO
和withSqlitePool
這樣做,但這會導致測試效率低下。每個測試,而不是屬性,但測試,將創建和銷燬數據庫池。我如何防止這種情況?如何使用QuickCheck測試與數據庫相關的功能?
重要提示:忘記效率或優雅。我還沒有能夠使QuickCheck
和Persistent
類型甚至組成。
instance (Monad a) => MonadThrow (PropertyM a)
instance (MonadThrow a) => MonadCatch (PropertyM a)
type NwApp = SqlPersistT IO
prop_childCreation :: PropertyM NwApp Bool
prop_childCreation = do
uid <- pick $ UserKey <$> arbitrary
lid <- pick $ LogKey <$> arbitrary
gid <- pick $ Aria2Gid <$> arbitrary
let createDownload_ = createDownload gid lid uid []
(Entity pid _) <- run $ createDownload_ Nothing
dstatus <- pick arbitrary
parent <- run $ updateGet pid [DownloadStatus =. dstatus]
let test = do
(Entity cid child) <- run $ createDownload_ (Just pid)
case (parent ^. status, child ^. status) of
(DownloadComplete ChildrenComplete, DownloadComplete ChildrenNone) -> return True
(DownloadComplete ChildrenIncomplete, DownloadIncomplete) -> return True
_ -> return False
test `catches` [
Handler (\ (e :: SanityException) -> return True),
Handler (\ (e :: SomeException) -> return False)
]
-- How do I write this function?
runTests = monadicIO $ runSqlite ":memory:" $ do
-- whatever I do, this function fails to typecheck
你可以給你快速檢查屬性之一的例子嗎? – ErikR
難道你只是想在'monadicIO'調用之外使用'withSqlitePool'嗎?例如,'tests = withSqlitePool $ \ pool - > do monadicIO(test1 pool); monadicIO(test2 pool)'。 –
我們使用':memory:'的SQLite連接(我認爲這或多或少只是一個內存中的SQLite數據庫)。它似乎工作得很好,當然足以永遠不會成爲一個瓶頸,但也許你正在比我們更多的移動數據。你應該做的緩慢艱難的事情是創建你自己的PersistStore實例,並用(例如)一堆'Data.Map'來實現它。但是這絕對會阻止你在'Database.Persist.Sql'中使用任何東西,在這種情況下,你需要花一個手臂和一條腿來構造'SqlBackend'值。 – hao