简体   繁体   English

单元测试F#中的私有方法

[英]unit test private methods in F#

Let's say we have a class 假设我们有一堂课

type ThisClassIsComplicated () = 
    let calculateSomething a b =
        a + b 

In this case calculateSomething is trivial, but if it would be more complicated it may make sense to verify that the calculations done there are correct. 在这种情况下, calculateSomething是微不足道的,但如果它更复杂,那么验证那里完成的计算是否正确可能是有意义的。

It might make sense to use a unit testing framework to test that private methods. 使用单元测试框架来测试私有方法可能是有意义的。

My question: how to unit test private methods in F#? 我的问题:如何在F#中对私有方法进行单元测试?

Some random thoughts: 一些随意的想法:

The selected answer here , suggests to use the InternalsVisibleTo attribute which anyway is applicable only to internal methods . 所选择的答案在这里 ,建议使用InternalsVisibleTo属性这反正是只适用于internal方法

What is the route specific to F# if any? F#特有的路由是什么? Is this better in a F# design? 这在F#设计中更好吗?

let calculateSomething a b = a + b 

type ThisClassIsComplicated () = 
    member this.Calculate a b = calculateSomething a b

Maybe the scope of calculateSomething could be even narrowed down by having a nested module . 也许通过嵌套模块可以缩小calculateSomething的范围。

If you feel like your code is too complicated to test it from the outside, use the latter option. 如果您觉得您的代码太复杂而无法从外部进行测试,请使用后一选项。 And in case you want to test an inner function like 如果你想测试一个内部函数,如果

let myComplicatedOperation input = 
    let calculateSomething a b =
        a + b
    calculateSomething (fst input) (snd input)

you can always rewrite it with currying like this: 你总是可以用这样的currying重写它:

let myComplicatedOperation calculateSomething input =
    calculateSomething (fst input) (snd input)

Your question does not seem to be directly related to F# though. 你的问题似乎与F#没有直接关系。 The general way to test private methods is typically by extracting a class (or, in F#, you can also just extract a let bound function). 测试私有方法的一般方法通常是通过提取类(或者,在F#中,您也可以只提取一个let绑定函数)。 And making your testee public on that other class / function. 并让你的被测者公开其他课程/职能。

I think that loosening access restrictions in a class/module to facilitate testing is often a bad idea. 我认为放松类/模块中的访问限制以便于测试通常是一个坏主意。 If you have decided something is irrelevant to know for the outside world, you wanting to test it doesn't make it any less irrelevant. 如果你已经确定某些东西与外界知道无关,你想要测试它并不会使它变得不那么无关紧要。

Can't you just have a public method/function in your class/module that does the testing? 难道你不能在你的类/模块中有一个公共方法/函数来进行测试吗?

type ThisClassIsComplicated () = 
    let calculateSomething a b =
        a + b 

    member private this.TestInstance () = 
        printfn "%A" <| calculateSomething 1 2

    static member Test () = 
        (new ThisClassIsComplicated()).TestInstance()

You can use Impromptu Interface to invoke private methods. 您可以使用Impromptu Interface来调用私有方法。

For example, I test the function calcNodeLabel at https://code.google.com/p/fseye/source/browse/trunk/FsEye/Forms/WatchTreeView.fs#73 like so: https://code.google.com/p/fseye/source/browse/trunk/Test.FsEye/WatchTreeViewLabelCalculatorTests.fs#54 例如,我在https://code.google.com/p/fseye/source/browse/trunk/FsEye/Forms/WatchTreeView.fs#73上测试函数calcNodeLabel ,如下所示: https//code.google.com /p/fseye/source/browse/trunk/Test.FsEye/WatchTreeViewLabelCalculatorTests.fs#54

But you need to be careful testing hidden functions in F#: it's an implementation detail of the compiler how the function will actually be compiled (eg as a method, as a delegate, as a ...). 但是你需要小心测试F#中的隐藏函数:它是编译器如何实际编译函数的实现细节(例如作为方法,作为委托,作为......)。

Folks will warn generally against testing private methods, but I think it is a bit simplistic to say "never test private methods", since such a declaration takes for granted that access levels as specified in the .NET framework are the only way they could be. 人们通常会警告不要测试私有方法,但我认为说“永不测试私有方法”有点过于简单,因为这样的声明理所当然地认为.NET框架中指定的访问级别是他们唯一的方式。 。

For example, calcNodeLabel in my example should indeed be hidden from the great wide world, but I would consider it part of the internal contract of the class. 例如,我的例子中的calcNodeLabel确实应该被广泛的世界所隐藏,但我认为它是该类内部契约的一部分。 Of course, you could argue that the class view data and the view itself should be separated, but the point stands: all models are imperfect! 当然,您可能会认为类视图数据和视图本身应该分开,但重点是:所有模型都不完美!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM