如何使用常见的Assert方法(F#)实施干净的基础测试类

时间:2018-12-09 19:50:11

标签: f#

我正在尝试创建一个基础测试类,可以在其中设置通用方法。

type BaseTest() =

    member self.Assert (functionToEvaluate:bool, ?errorMessage:string) =    
        let a = fun () -> defaultArg errorMessage ""    
        match errorMessage with
        | None -> NUnit.Framework.Assert.That(functionToEvaluate)
        | _ -> NUnit.Framework.Assert.That(functionToEvaluate, a )

[<TestFixture>]
type MyTest () =
    inherit BaseTest()

    [<Test>]
    member self.``test something``() =
        let x = 1
        self.Assert_( (x = 2))
        // or 
        self.Assert_( (x = 2), "x value is not 2")
  1. 如何使代码“干净”(let a ...对我来说很可怕)
  2. 如何避免在派生类中使用 this / self
  3. 我怎么能像self.Assert(x=1)这样写,或者甚至更像Assert(x=1)而不是self.Assert((x=1))

我想做的(我可以用C#做​​)是这样的:

// in base test class
protected void Assert(bool test) => NUnit.Framework.Assert.That(test);
protected void Assert(bool test, string errorMessage) => NUnit.Framework.Assert.That(test, errorMessage);

// in test class
public void TestSomething() {
     var x = 1
     Assert(x==2)
     // or
     Assert(x==2, "x is not 2")
}

1 个答案:

答案 0 :(得分:3)

您的问题是,您试图将C#程序逐字转换为F#,并希望它看起来“不错”,而没有意识到最初的C#程序已经充满了特定于C#的技巧,以便使它看起来像“不错”。一个例子是基类。为什么会有基类?它代表什么吗?不,不是这样的:它存在的唯一目的是在调用这些函数时避免使用类名-即,您编写的是Assert而不是SomeHelper.Assert。这源于以下事实:在C#中,您不能拥有独立的功能。

但是在F#中-您可以!

let assrt x = NUnit.Framework.Assert.That(x)
let assrtWith x msg = NUnit.Framework.Assert.That(x, msg)

[<TestFixture>]
type SaleRepositoryTest () =

    [<Test>]
    member self.``test something``() =
        let x = 1
        assrt (x=2)
        assrtWith (x=2) "x is not 2"

(请注意,您不能使用名称assert,因为它是一个关键字)

还请注意,您通常不需要课程。在C#中,如果没有它们,您将无能为力,这是Java设计产生的一个巨大错误,这是对OO的误解。

您可以具有独立功能。如果我没记错的话,NUnit应该能够很好地发现这样的测试(尽管我现在无法验证):

let [<Test>] ``test something``() =
    let x = 1
    assrt (x=2)
    assrtWith (x=2) "x is not 2"

最后,我强烈建议您考虑使用FsUnit。它可以绑定到NUnit(如果您被锁定在其中),并提供一个漂亮的F#惯用断言库。