我正在尝试创建一个基本测试类,在那里我可以设置通用方法。
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")
- 如何使代码"干净"(
let a ...
对我来说很可怕( - 如何避免在派生类中使用this/self
- 我怎么能像
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#惯用断言库。