Comparing Discriminated Unions

◇◆丶佛笑我妖孽 提交于 2019-12-07 06:13:37

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!