对于模糊的描述感到抱歉,找不到更好的方法来说明问题。
我开始使用F#和许多其他人一样,我正在将解决的Euler问题转换为F#。我喜欢使用测试运行我的代码,也喜欢FsUnit风格。在给定示例的帮助下,我做到了这一点:
open System
open NUnit.Framework
open FsUnit
type EulerProblem() =
member this.problem1 = Seq.init 999 (fun n -> n + 1)
|> Seq.filter (fun n -> n % 3 = 0 || n % 5 = 0)
|> Seq.sum
[<TestFixture>]
type ``Given an Euler problem`` () =
let euler = new EulerProblem()
[<Test>] member test.
``when I try to solve #1 should return [the magic number]`` ()=
euler.problem1 |> should equal [the magic number]
这有效,但我无法理解test
方法之后的时间段。如果我把它拿走,编译器投诉说:
此实例成员需要一个参数来表示要调用的对象。使成员静态或使用符号'member x.Member(args)
很抱歉,如果这是微不足道的,也许我没有使用正确的措辞,但无法通过谷歌得到答案。
由于
答案 0 :(得分:4)
如果您熟悉C#,Java或C ++,则可以使用实例成员中的this
保留字来引用类实例。在F#中,您必须为每个成员定义的类实例显式命名,在FsUnit示例中,给出的名称仅为test
,但实际上并未使用。您可以将测试方法编写为
[<Test>] member this.
``when I try to solve #1 should return [the magic number]`` ()=
euler.problem1 |> should equal [the magic number]
但是请注意,现在,xUnit.net和NUnit都允许分别应用他们的[<Fact>]
和[<Test>]
属性来标记模块内的let绑定函数的测试,而不需要TestFixture
和这样,更适合F#。所以,例如,你给出的测试可以并且在我看来应该写成:
module EulerProblemTests () =
[<Test>]
let ``when I try to solve #1 should return [the magic number]`` () =
let euler = new EulerProblem()
euler.problem1 |> should equal [the magic number]
此外,您可能不希望将问题解决方案创建为type
EulerProblem
的成员,而不是模块中的函数。
答案 1 :(得分:2)
它仍然是一个类,因此每个成员必须是静态的,或者定义了“this”。
在你的测试中,“test”是会员的“this”。
通常这个课程看起来像这样:
type ClassName() =
member thisname.MethodName() =
DoSomeStuff |> DoMoreStuff
对于句号,正在使用“测试”一词,没有它就不知道它是什么类型的成员。