鉴于我有IO功能: // this can either be IO or some other side effect //that makes the function less pureprintf "HI" 我想测试IO被正确调用.测试IO被正确调用的必要解决方案是将IO语句包装在对象中,模拟对象
// this can either be IO or some other side effect //that makes the function less pure printf "HI"
我想测试IO被正确调用.测试IO被正确调用的必要解决方案是将IO语句包装在对象中,模拟对象,使用依赖注入传递对象,并验证使用正确的参数调用正确的方法.我想知道如果不是使用依赖注入来测试F#,更好的方法是检查函数的输出(通过声明返回正确的值或函数)并删除IO调用;因此,通过消除IO调用的副作用,使功能再次变为纯净.
我正在考虑将所有IO包装在一个特殊的模块中.
let MyPrint print statement = print statement ; statement
所以我可以删除IO函数并在我的测试中断言正确的操作发生如下:
被测代码:
let PrintHi = fun(print) -> MyPrint print "HI" let DoNothing = fun(print) -> () let DoIf conditional = if conditional then PrintHi else DoNothing
FsUnit:
[<Test>] member test. let printStub value = () ``Test Hi Is Printed When TRUE`` ()= let testedFunc = DoIf true testedFunc(printStub) |> should equal PrintHi(printStub)
这是测试IO副作用的好方法吗?有没有更好的办法?请记住,我的目标是测试任何IO,而不仅仅是打印声明.
一般来说,您需要将纯代码与不纯(副作用)代码分开;并保持代码尽可能纯净.我建议阅读这些有关它的文章,它们是为其他函数式语言编写的,但它们使用的代码很简单,概念很好地解释,可以很容易地应用于F#(以及许多其他语言):
> Introduction to QuickCheck (Haskell wiki)
> How to write a functional program with IO, mutation, and other effects