比较受歧视的联盟

时间:2011-09-14 23:52:49

标签: f# discriminated-union fsunit

我是F#的新手,我正在玩FParsec。我会使用FParsec生成AST。我想使用FsUnit围绕解析器的各个部分编写一些测试,以确保正确的操作。

我在语法上遇到了一些麻烦(对不起,确切的代码在起作用,我可以稍后发布一个具体的例子)所以如何比较两个受歧视的联合(一个是预期的,另一个是实际的)结果)?有人可以使用FsUnit(或NUnit)提供一个很小的代码示例吗?

示例区分联合(非常简单)

type AST = 
    | Variable of string
    | Class of string
    | Number of int

2 个答案:

答案 0 :(得分:6)

正如Brian指出的那样,F#联合体具有结构上的平等性,使用您喜欢的任何单元测试框架都很容易。

FsUnit是一个基于NUnit构建的F#特定库。我个人最喜欢的F#特定单元测试库是Unquote ,;),它与框架无关,与NUnit,xUnit.net,MbUnit,甚至在FSI中都能很好地协同工作。您可能对this与FsUnit的比较感兴趣。

那么,你如何使用NUnit + Unquote做到这一点?这是一个完整的工作示例:

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") @>

然后使用TestDriven.NET运行测试,输出如下:

------ 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).

答案 1 :(得分:2)

示例 - 如果要检查类型而不是内容

let matched x= 
    match x with
    |Variable(_) -> true
    | _ -> false

请注意,您需要为受歧视的联合的每个元素使用不同的函数

如果你想比较平等,你可以用标准的方式来做,比如

Assert.AreEqual(Variable("hello"),result)

if result = Variable("hello") then stuff()