Here we have a simple interface:
type SomeRecord = {
ID : int
Name : string
}
type IDatabase =
abstract member Get: int -> SomeRecord
abstract member Save: SomeRecord -> bool
Here is the normal way to implement an interface:
type RealDatabase() =
interface IDatabase with
member this.Save x = // database get implementation
member this.Get record = // database save implementation
This could be used in code as follows (admittedly a rather contrived example):
let Service (db:IDatabase) id = db.Get id
When writing a unit test for this function we could create a test class implementing the interface. But, using F# allows creating an instance of the interface on the fly which makes testing really easy like so:
[<fact>]
let ``Some unit test``() =
let fakeDb = { new IDatabase with
member this.Save record = true
member this.Get id = {ID = id; Name = "Test"} }
(Service fakeDb 2) |> should equal {ID = 2; Name = "Test"}
This is much easier than using a moq library. The ability to easily create classes implementing an interface without much code is another reason I really like F#. The language doesn't get in the way when trying to accomplish a task.
No comments:
Post a Comment