问题
I'm a newbie to F# and I'm playing around with FParsec. I would use FParsec to generate an AST. I would like to use FsUnit to write some tests around the various parts of the parser to ensure correct operation.
I'm having a bit of trouble with the syntax (sorry, the exact code is at work, I can post a specific example later) so how exactly could one compare two discriminated unions (one the expected, the other the actual result)? Could someone provide a tiny code example using FsUnit (or NUnit), please?
An example discriminated union (very simple)
type AST =
| Variable of string
| Class of string
| Number of int
回答1:
Since, as Brian pointed out, F# unions have structural equality, this is easy using whichever unit testing framework you are fond of.
FsUnit is an F# specific library built on top of NUnit. My personal favorite F# specific unit testing library is Unquote, ;), which is framework agnostic, working very well with NUnit, xUnit.net, MbUnit, ... or even within FSI. You may be interested in this comparison with FsUnit.
So, how would you do this with NUnit + Unquote? Here's a full working example:
module UnitTests
open NUnit.Framework
open Swensen.Unquote
type AST =
| Variable of string
| Class of string
| Number of int
let mockFParsec_parseVariable input = Variable(input)
[<Test>]
let ``test variable parse, passing example`` () =
test <@ mockFParsec_parseVariable "x" = Variable("x") @>
[<Test>]
let ``test variable parse, failing example`` () =
test <@ mockFParsec_parseVariable "y" = Variable("x") @>
Then running the tests using TestDriven.NET, the output is as follows:
------ Test started: Assembly: xxx.exe ------
Test 'UnitTests.test variable parse, failing example' failed:
UnitTests.mockFParsec_parseVariable "y" = Variable("x")
Variable "y" = Variable("x")
false
C:\xxx\UnitTests.fs(19,0): at UnitTests.test variable parse, failing example()
1 passed, 1 failed, 0 skipped, took 0.80 seconds (NUnit 2.5.10).
回答2:
An example - if you want to check the type but not the contents
let matched x=
match x with
|Variable(_) -> true
| _ -> false
Note here that you need a different function for each element of the discriminated union
If you want to compare equality, you can just do it in the standard way, like
Assert.AreEqual(Variable("hello"),result)
or
if result = Variable("hello") then stuff()
来源:https://stackoverflow.com/questions/7424332/comparing-discriminated-unions