2015-12-09 4 views
3

Я пытаюсь написать тесты HUnit для функций haskell, которые возвращают IO-монад, потому что они выполняют ввод/вывод файлов. Есть какой-либо способ сделать это? Сейчас я пытаюсь написать метод, который просто возвращает Bool, и это может быть мой тестТесты Haskell с использованием IO monad

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 

, но это дает мне следующую ошибку:

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

Ну, типа хорошие юнит-тесты, чтобы начать с! Попробуйте 'return (z == a && b == y)'. – luqui

+0

Есть ли способ обернуть это в тест hunit? – astiefel

+2

@astiefel HUnit 'Assertion' - это просто' IO() ', так что да. Правильнее было бы, вероятно, сделать 'assertEqual" ... "z a; assertEqual "..." b y' - таким образом вы можете указать причины, по которым они должны быть равными, а когда ваш тест провалится, вам будет легче выяснить, почему. – user2407038

ответ

1

Как и то, что @ user2407038 сказал в комментариях и, как указано в HUnit user manual Испытания HUnit, запущенные в IO monad.

Вот пример:

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}