gpt4 book ai didi

unit-testing - 在 F# 单元测试中检查函数相等性

转载 作者:行者123 更新时间:2023-12-03 11:12:38 26 4
gpt4 key购买 nike

我有一堆 F# 函数,它们为相同的输入实现不同的算法,有点像策略模式。为了选择正确的策略,我想对输入参数进行模式匹配并将函数作为值返回:

let equalStrategy points : seq<double> =
...

let multiplyStrategy factor (points: seq<double>) =
...

let getStrategy relationship =
match relationship with
| "=" -> equalStrategy
| "*5" -> multiplyStrategy 5.0
| _ -> raise (new System.NotImplementedException(" relationship not handled"))

现在我想编写一些单元测试来确保我返回正确的策略,所以我在 nUnit 中尝试了这样的事情:
    [<TestCase("=")>]
[<Test>]
member self.getEqualstrategy( relationship:string ) =
let strategy = getStrategy relationship

Assert.AreEqual( strategy, equalStrategy )

现在我认为代码是正确的并且会做我想做的事,但是断言失败了,因为函数似乎没有定义相等操作。所以我的问题是:

(a) 有没有办法比较两个函数以查看它们是否相同,即让 isFoo bar = foo == bar,我可以在 nUnit 断言中使用?

或者

(b) 是否有另一个单元测试框架可以在 F# 中为我做这个断言?

最佳答案

测试您的 getStrategy 是否返回 F# 函数与您定义的功能之一相同的功能也基本上是不可能的。

提供一些细节 - F# 编译器生成一个继承自 FSharpFunc 的类当您将函数作为值返回时。更重要的是,每次创建函数值时它都会生成一个新类,因此无法比较类的类型。

生成的类的结构是这样的:

class getStrategy@7 : FSharpFunc<IEnumerable<double>, IEnumerable<double>> {
public override IEnumerable<double> Invoke(IEnumerable<double> points) {
// Calls the function that you're returning from 'getStrategy'
return Test.equalStrategy(points);
}
}

// Later - in the body of 'getStrategy':
return new getStrategy@7(); // Returns a new instance of the single-purpose class

原则上,您可以使用反射来查看 Invoke 内部。方法并找到从那里调用哪个函数,但这不是一个可靠的解决方案。

在实践中 - 我认为您可能应该使用其他一些更简单的测试来检查 getStrategy函数返回正确的算法。如果你在几个样本输入上运行返回的策略,这应该足以验证返回的算法是正确的,并且你不会依赖于实现细节(例如 getStrategy 函数是否只返回一个命名的函数或它是否返回具有相同行为的新 lambda 函数。

或者,您可以将函数包装在 Func<_, _> 中委托(delegate)并使用与 C# 相同的方法。但是,我认为检查是否 getStrategy返回一个特定的引用是一个过于详细的测试,它只会限制你的实现。

关于unit-testing - 在 F# 单元测试中检查函数相等性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8225433/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com