2017-01-17 1 views
0

J'ai trouvé d'autres questions sur des lignes similaires mais rien qui réponde à ma question dans ce scénario particulier. De plus, il semble y avoir peu de ressources qui couvrent succinctement le sujet des actions d'E/S des tests unitaires chez Haskell.Test d'unité Actions d'E/S avec Hspec

Disons que j'ai cette classe de types pour ma communication de base de données:

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 

et cette fonction qui l'utilise:

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

Je souhaite tester cette fonction getIt avec hspec mais sans lui parler la base de données, qui signifie vraisemblablement le remplacement MonadDB qu'il utilise, mais comment puis-je y parvenir?

Répondre

2

Cela fonctionnerait-il pour vous?

#!/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") 

Vous pourriez également être en mesure d'utiliser ReaderT ou StateT aux données « d'approvisionnement » ou une transformation pour getSomething à utiliser lors de l'interrogation de test.

Édition: Exemple d'utilisation depuis hspec.

+0

Merci. Comment votre test s'exécuterait-il dans une spécification HSpec? –

+0

Mis à jour ma réponse. –

+0

Le 'MonadDB' étant un paquet différent a-t-il une influence sur la capacité du compilateur à sélectionner l'instance' IdentityT m'? –