2015-12-09 3 views
3

J'essaie d'écrire des tests HUnit pour les fonctions de haskell qui renvoient des monops IO car ils effectuent des E/S de fichiers. Est-ce qu'il y a un moyen de faire ça? En ce moment je suis en train d'écrire une méthode qui retourne juste un Bool et qui peut être mon testHaskell Tests unitaires utilisant la monothèque IO

combine :: FilePath -> FilePath -> Bool 
combine fp1 fp2 = do 
    cs <- readFile fp1 
    let (_,y,z) = strToHuff cs 
    let _ = writeToFile fp2 z y 
    (a, b) <- readFromFile fp2 
    z == a && b == y 

mais qui me donne l'erreur suivante:

FileWriter.hs:153:3: Couldn't match type ‘IO b0’ with ‘Bool’ … 
    Expected type: IO String -> (String -> IO b0) -> Bool 
     Actual type: IO String -> (String -> IO b0) -> IO b0 
    In a stmt of a 'do' block: cs <- readFile fp1 
    In the expression: 
     do { cs <- readFile fp1; 
      let (_, y, z) = strToHuff cs; 
      let _ = writeToFile "try1.txt" z y; 
      (a, b) <- readFromFile fp2; 
      .... } 
    In an equation for ‘combine’: 
     combine fp1 fp2 
      = do { cs <- readFile fp1; 
       let (_, y, z) = ...; 
       let _ = ...; 
       .... } 
FileWriter.hs:157:3: Couldn't match expected type ‘IO b0’ with actual type ‘Bool’ … 
    In a stmt of a 'do' block: z == a && b == y 
    In the expression: 
     do { cs <- readFile fp1; 
      let (_, y, z) = strToHuff cs; 
      let _ = writeToFile "try1.txt" z y; 
      (a, b) <- readFromFile fp2; 
      .... } 
    In an equation for ‘combine’: 
     combine fp1 fp2 
      = do { cs <- readFile fp1; 
       let (_, y, z) = ...; 
       let _ = ...; 
       .... } 
Compilation failed. 
+0

Eh bien, les types sont de bons tests unitaires pour commencer! Essayez 'return (z == a && b == y)'. – luqui

+0

Existe-t-il un moyen de l'emballer dans un test de dépistage? – astiefel

+2

@astiefel Un 'Assertion' HUnit est juste un 'IO()' donc oui vous pouvez. La bonne chose serait probablement de faire 'assertEqual" ... "z a; assertEqual "..." b y' - De cette façon, vous pouvez expliquer les raisons pour lesquelles celles-ci doivent être égales et lorsque votre test échouera, vous aurez plus de facilité à déterminer pourquoi. – user2407038

Répondre

1

Comme quoi @ user2407038 dit dans les commentaires et comme mentionné dans les tests HUnit user manual HUnit s'exécutent dans le IO monad.

est un exemple:

testFilesEqual = TestCase (do x <- readFile "a.txt" 
           y <- readFile "b.txt" 
           assertEqual "files not equal" x y) 
# a.txt == b.txt 
λ> runTestTT testFilesEqual 
Cases: 1 Tried: 0 Errors: 0 Failures: 0 
Counts {cases = 1, tried = 1, errors = 0, failures = 0} 

# a.txt != b.txt 
λ> runTestTT testFilesEqual 
### Failure: 
files not equal 
expected: "hello\n" 
but got: "world\n" 
Cases: 1 Tried: 1 Errors: 0 Failures: 1 
Counts {cases = 1, tried = 1, errors = 0, failures = 1}