2017-01-17 5 views
0

유사한 줄에 다른 질문이 있지만이 특정 시나리오에서 내 질문에 대한 답변이 없습니다. 게다가 Haskell에서 단위 테스트 IO 작업의 주제를 간략하게 설명하는 리소스가 거의없는 것 같습니다.Hspec을 사용한 IO 작업 단위 테스트

의 내가 내 데이터베이스 통신이 typeclass 있다고 가정 해 봅시다 :

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 

과 사용이 기능 :

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

내가 hspec에 있지만 이야기하지 않고 getIt 기능을 테스트 할 아마도 데이터베이스를 교체하는 것이므로 MonadDB을 사용하지만 그 작업을 어떻게 수행합니까?

답변

2

이 기능을 사용할 수 있습니까?

#!/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 
    [email protected](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") 

또한 테스트 쿼리에 사용하는 getSomething에 대한 ReaderT 또는 StateT에 "공급"데이터 또는 변환을 사용할 수 있습니다.

편집 : 예제는 hspec에서 사용합니다.

+0

감사합니다. 귀하의 테스트는 HSpec 사양에서 어떻게 실행됩니까? –

+0

내 대답이 업데이트되었습니다. –

+0

'MonadDB'가 다른 패키지 인 경우 컴파일러가 'IdentityTm' 인스턴스를 선택할 수있는 능력에 어떤 영향을 줍니까? –