I'm trying to write a test for a small lib I'm writing that (essentially) just logs to the console.
Is there a way to mock function like this is F#?
example: in src/Lib/Lib.fs
module Lib
let print msg = printfn "Your message is: %s" msg
then, in 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"
Note: I'm aware that currently print
returns unit
- I am looking for a way to make assertions about what is passed to printfn
(or, more ideally, what is sent to stdout, which relies less on implementation).
I've tried directly assigning a mock function to Printf.printfn
to no avail (obviously, when I think about it). Is it possible to capture the output to the console? Or to mock the printfn
function (it's an implementation detail, but I can live with that).
This is what I use for testing:
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
The code I am testing calls printoutfn
or printoutfns
which is the silent version.
To test the output I do it like this:
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"
Notice how it includes the newline character: \\n
.
There are two invocations: StdOut.call func param
and StdOut.run func param
the former returns the function value and the output, the latter only returns the output
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.