F# Usage
F# usage
FluentAssertions was made with C# in mind. While it can be used from F#, the experience will not always be as intended.
For a better F# experience we encourage F# developers to try out Faqt, an assertion library inspired by FluentAssertions and made specifically for F#.
Some of the awkwardness you might hit with FluentAssertions when using F# is:
-
To aid F#’s overload resolution, you often have to cast subject values. This does not work in all cases and will only give you a subset of assertions. For example:
let x = [1; 2] x.Should().Contain(1, "") // Overload resolution error for "Should" (x :> seq<_>).Should().Contain(1, "") // OK, but only gives access to GenericCollectionAssertions<_>
The need to cast will break your fluent chains, defeating some of the purpose of FluentAssertions.
-
Sometimes not even casting will solve the issue, and you will have to forgo
Should
entirely and instead directly construct the correct assertion type. For example:let x = dict ["A", 1; "B", 2] // All of these give overload resolution errors for "Should" x.Should().ContainKey(1, "") (x :> IDictionary<_,_>).Should().ContainKey(1, "") (x :> seq<KeyValuePair<_,_>>).Should().Contain(KeyValuePair("A", 1), "") // You have to construct the desired assertion directly GenericDictionaryAssertions<_, _, _>(x).ContainKey("A", "") GenericCollectionAssertions<_, _, _>(x).Contain(KeyValuePair("A", 1), "")
As with casting, the need to construct the assertion directly will break your fluent chains, defeating one of the key points of FluentAssertions.
- As can be seen above, the
because
parameter cannot be omitted when used from F# (#2225). Adding overloads with a fixedbecause
is deemed out of scope for the main FluentAssertions package since it would double the API surface. - Several assertions (specifically, those that accept an
Action<_>
) require an explicitignore
when used from F# (#2226).