Normally I write my unit tests in F# as
open Swensen.Unquote
open Xunit
module MyTests =
[<Fact>]
let ``SomeFunction should return 10`` () =
let a = SomeFunction()
test <@ a = 10 @>
[<Fact>]
let ``SomeOtherFunction should return 11`` () =
let a = SomeFunction()
test <@ a = 11 @>
If I wish to log to the console from xunit ( according to http://xunit.github.io/docs/capturing-output.html ) one needs to write a constructor that takes an ITestOutputHelper and then use that instead of Console.WriteLine and family.
using Xunit;
using Xunit.Abstractions;
public class MyTestClass
{
private readonly ITestOutputHelper output;
public MyTestClass(ITestOutputHelper output)
{
this.output = output;
}
[Fact]
public void MyTest()
{
var temp = "my class!";
output.WriteLine("This is output from {0}", temp);
}
}
however fsharp modules are static classes and the tests are static methods. There is no constructor to inject the output helper.
Is there a way to get access to the current output helper for the current test. I know I could rewrite my fsharp tests to be non static classes but that is undesired.
After looking at the XUnit source.
https://github.com/xunit/xunit/blob/e64f566b75f93cd3cec27f950759d82832bfe44b/src/xunit.execution/Sdk/Frameworks/Runners/TestClassRunner.cs#L90
I'm pretty sure this is an overlooked case. There is no injection of the helper into static classes.
If xUnit does not have any alternative mechanism for injection of the parameters, then I guess the only option is to define the tests as methods in an F# object type. I also prefer writing tests as functions using let
, but the following simple object type does not look too bad:
open Swensen.Unquote
open Xunit
open Xunit.Abstractions
type MyTests(output:ITestOutputHelper) =
[<Fact>]
member __.``SomeFunction should return 10`` () =
let a = SomeFunction()
output.WriteLine("Some function returned {0}", a)
test <@ a = 10 @>
It would be nice if xUnit supported some other option for this - I suspect that they might be open to suggestions, if it is something that would not be too awkward (perhaps using a method parameter?)
But unless xUnit adds support for some other method, I think you'll need to use F# object with methods.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With