如何用常见的Assert方法(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")
}

您的问题是,您试图将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#惯用断言库。

最新更新