0

我正在尝试为我正在编写的一个小库编写一个测试(基本上)只是记录到控制台。

有没有办法像 F# 这样模拟函数?

示例:在 src/Lib/Lib.fs

module Lib

let print msg = printfn "Your message is: %s" msg

然后,在 test/LibTest/Lib.fs

module LibTest

open NUnit.Framework
open FsUnit

[<Test>]
let ``should print what I expect``() =
  print "test" |> should equal "Your message is: test"

注意:我知道当前print返回unit- 我正在寻找一种方法来断言传递给的内容printfn(或者,更理想的是,发送给 stdout 的内容,它较少依赖于实现)。

我试过直接分配一个模拟函数Printf.printfn无​​济于事(显然,当我想到它时)。是否可以将输出捕获到控制台?或者模拟printfn函数(这是一个实现细节,但我可以接受)。

4

1 回答 1

0

这是我用于测试的:

module StdOut =
    let stdout = System.Text.StringBuilder()
    let out (s:string) = stdout.Append s |> ignore
    let call func parm =
        stdout.Clear() |> ignore
        func parm, stdout.ToString()
    let run f p = call f p |> snd

let inline  (|>!) v f   = f v ; v
/// used to capture print outs for testing. like printfn
let printoutfn  fmt = fmt |> Printf.ksprintf (fun s -> s + "\n" |>! printf "%s"|> StdOut.out)
/// silent version of printoutfn
let printoutfns fmt = fmt |> Printf.ksprintf (fun s -> s + "\n"                |> StdOut.out)
let printout      v = printoutfn "%A" v

我正在测试的代码调用printoutfn或者printoutfns是静默版本。

为了测试输出,我这样做:

let print msg = printoutfn "Your message is: %s" msg

[<Test>] 
let ``should print what I expect``() =
      StdOut.run print "test" |> should equal "Your message is: test\n"

注意它是如何包含换行符的:\n.

有两种调用:前者返回函数值和输出,后者只返回StdOut.call func param输出StdOut.run func param

于 2018-10-15T09:47:44.590 回答