Tuesday, March 15, 2016

My Favorite F# Feature - Creating an Anonymous Class from an Interface

There are a lot of delightful F# language features and the best may be the ability to create an anonymous class implementing an interface. When I first discovered this feature I jumped out of my chair with excitement. Let's walk through a simple scenario.

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