代码之家  ›  专栏  ›  技术社区  ›  Alex 75

如何使用公共断言方法(f)实现干净的基本测试类

f#
  •  0
  • Alex 75  · 技术社区  · 6 年前

    我正在尝试创建一个基本测试类,在那里我可以设置公共方法。

    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. 如何避免使用 这个/自己 在派生类中?
    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 回复  |  直到 6 年前
        1
  •  3
  •   Fyodor Soikin    6 年前

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