I want to unit test this bit of code using xUnit in F#. How do I handle the options?
From Scott Wlaschin's book: Domain Modeling Made Functional
type UnitQuantity = private UnitQuantity of int
// ^ private constructor
// define a module with the same name as the type
module UnitQuantity =
/// Define a "smart constructor" for UnitQuantity
/// int -> Result<UnitQuantity,string>
let create qty =
if qty < 1 then
// failure
Error "UnitQuantity can not be negative"
else if qty > 1000 then
// failure
Error "UnitQuantity can not be more than 1000"
else
// success -- construct the return value
Ok (UnitQuantity qty)
Test:
let ``Check UnitQuantity.create is one`` () =
// ARRANGE
let expected = 1
// ACT
//let unitQtyResult = UnitQuantity.create 1
match UnitQuantity.create 1 with
| Error msg -> 0
//printfn "Failure, Message is %s" msg
| Ok x -> 0
// let innerValue = UnitQuantity.value actual
// ASSERT
//Assert.Equal(expected,actual)
I know the ACT
is all wrong, that is where I am hung up. I do not understand F# options nor xUnit.net nor unit testing enough yet to Assert on the actual value from the function.
F-Test in Excel. F-test in excel is a test which is used to decide if two populations having normal distribution have similar variances or the standard deviation. This is an essential part of the Analysis of Variance (ANOVA).
For an overall F-test, the ratio contains the variance accounted for by your model in the numerator and the variance accounted for by a model with no predictors in the denominator. If the ratio is significantly greater than one, you know that the numerator is significantly greater than the denominator.
F value is a value on the F distribution. Various statistical tests generate an F value. The value can be used to determine whether the test is statistically significant. In order to compare two variances, one has to calculate the ratio of the two variances, which is as under: F Value = Larger Sample Variance / Smaller Sample Variance = σ12 / σ22.
(Step by Step) | Examples F-test formula is used in order to perform the statistical test that helps the person conducting the test in finding that whether the two population sets that are having the normal distribution of the data points of them have the same standard deviation or not. F-Test is any test that uses F-distribution.
I'd probably compare the result directly rather than pattern matching. However, you can't create an Ok
result for Result<UnitQuantity, string>
because of the private
constructor.
You can use the built-in Result.map
to map the Ok
value of a result. Using UnitQuantity.value
you can map from Result<UnitQuantity, string>
to Result<int, string>
. So this should work:
let expected = Ok 1
let actual = UnitQuantity.create 1 |> Result.map UnitQuantity.value
Assert.Equal(expected, actual)
A general rule of thumb with unit tests is that the Act section should be a single statement.
Everything that we want to check about the result is some form of assertion
So we want to assert whether the result is either an Ok<UnitQuantity>
or an Error<string>
.
This is where pattern matching allows us to test this very succintly
let ``Check UnitQuantity.create is one`` () =
// ARRANGE
let qty = 1 // The quantity we supply is one
let expected = qty // We expect to get that value back
// ACT
let actual = UnitQuantity.create qty
// ASSERT
// Check if we have an Ok or an Error
match actual with
| Ok unitQuantity ->
// If Ok, check the value is what we expect
let innerValue = UnitQuantity.value unitQuantity
Assert.Equal(innerValue, expected)
// If Error raise an AssertException to fail the test
| Error errorMessage ->
let error = sprintf "Expected Ok, was Error(%s)." errorMessage
Assert.True(false, error) // Force an assertion failure with our error message
Note the UnitQuantity.value
method, it' a simple unwrap function you can add to the end of the UnitQuantity
module that will give you back the int
value so you can easily compare it
let value (UnitQuantity e) = e
If you wanted to test an option
type, it would be very similar, using a match statement like so
match actual with
| Some value ->
// Do your assertions here
()
| None ->
// Do your assertions here
()
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