Haskell 使用 IO monad 进行单元测试
Haskell Unit tests using IO monad
我正在尝试为 haskell 函数编写 HUnit 测试,这些函数 return IO monads 因为它们执行文件 I/O。有什么办法吗?现在我正在尝试编写一个方法,它只是 return 一个 Bool 并且可以作为我的测试
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.
就像@user2407038 在评论中所说的和 HUnit user manual HUnit tests run in the 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}
我正在尝试为 haskell 函数编写 HUnit 测试,这些函数 return IO monads 因为它们执行文件 I/O。有什么办法吗?现在我正在尝试编写一个方法,它只是 return 一个 Bool 并且可以作为我的测试
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.
就像@user2407038 在评论中所说的和 HUnit user manual HUnit tests run in the 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}