简体   繁体   English

使用Hspec进行单元测试IO操作

[英]Unit testing IO actions with Hspec

I have found other questions on similar lines but nothing that answers my question in this particular scenario. 在类似的情况下,我发现了其他问题,但是在这种特定情况下,没有任何问题可以回答我的问题。 Furthermore, there seem to be few resources which succinctly cover the subject of unit testing IO actions in Haskell. 此外,似乎几乎没有资源可以简单地涵盖Haskell中的单元测试IO操作的主题。

Let's say I have this typeclass for my database communication: 假设我的数据库通信具有此类型类:

data Something = Something String deriving Show

class MonadIO m => MonadDB m where
  getSomething :: String -> m Something
  getSomething s = do
    ... -- assume a DB call is made and an otherwise valid function

instance MonadDB IO 

and this function which uses it: 和使用它的函数:

getIt :: MonadDB m => m (Int, Something)
getIt = do
  s@(Something str) <- getSomething "hi"
  return (length str, s) -- excuse the contrived example

I wish to test this getIt function with hspec but without it talking to the database, which presumably means replacing which MonadDB it uses, but how do I achieve that? 我希望使用hspec测试此getIt函数,但不与数据库进行通信,这大概意味着要替换它使用的MonadDB ,但是我如何实现呢?

Would this work for you? 这对您有用吗?

#!/usr/bin/env stack
-- stack exec --package transformers --package hspec -- ghci
import Control.Monad.IO.Class
import Control.Monad.Trans.Identity

import Data.Char
import Test.Hspec

data Something = Something String deriving (Eq, Show)

class MonadIO m => MonadDB m where
  getSomething :: String -> m Something
  getSomething s = return $ Something (map toUpper s)

instance MonadDB IO

instance MonadIO m => MonadDB (IdentityT m)

getIt :: MonadDB m => m (Int, Something)
getIt = do
  s@(Something str) <- getSomething "hi"
  return (length str, s)

main :: IO ()
main = hspec $ do
  describe "Some tests" $ do
    it "test getIt" $ do
      runIdentityT getIt `shouldReturn` (2, Something "HI")

    it "test getIt should fail" $ do
      runIdentityT getIt `shouldReturn` (1, Something "HI")

You might also be able to use ReaderT or StateT to "supply" data or a transformation for getSomething to use upon test querying. 您也许还可以使用ReaderTStateT为测试查询“提供”数据或getSomething的转换。

Edit: Example use from within hspec. 编辑:在hspec中使用示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM