F#: Creating your own mocks using Object Expressions… Wow

This just in from the “Wow, I can’t believe how easy this is” update desk:

You can roll your own mocks “dynamically”, even when mocking an interface. No, this isn’t too good to be true. No that weird tingling isn’t from your bullsh@# meter going off. (But you really should get that tingling checked by a doctor) This is F#. And this isn’t SPARTA!!! AHRHARHARHRAhRHARHR SO FUNAY!11

Say you have a test method that wants to call a method Validate on the Validator : IValidator class. Here is the IValidator class:

  type IValidator<'a, 'b> =
    abstract AddValidationMethod : ('a -> MethodResult<'b>) -> IValidator<'a, 'b>

(Side note: the ‘a and ‘b are just F#’s generic notation. Generic members are preceeded by a ‘)

Somewhere in your code this IValidator is called by someone, say a controller action:

  member public x.LoginPost(userName:String, password:String) =
    let loginModel = new LoginModel(userName, password)
    let result = x.ControllerValidator.Validate(loginModel)

And of course you would have a controller definition look like this:

  type MainController(validator:IValidator<LoginModel, LoginModel>) =
    inherit Controller()
      member private x.ControllerValidator with get() = validator

So you are set up for mocking.

There are three way, but if you’re already bored (And I assume you are) then just go to 3.

1) Mock the IValidator

As you can imagine, this could be obnoxious to mock up as the AddValidationMethod is adding a method that takes in ‘a and a MethodResult<‘a> and then returns an IValidator<‘a, ‘b>. Can it be done? I would asssume so, but there is another way.

2) Create a new class (Class file) that implements IValidator.

This is the most simple way of doing it. You just make a class that implements IValidator and just pass back what you want. Problem is: This isn’t very reusable as it is now a static class.

3) Create a class on the fly.

And this is the good stuff. F# allows the creation of a class (That implements an interface) “inline”… not sure what word I’m looking for so just go with it.

  let validatorWithFalseReturn = 
    { 
      new IValidator<'a, 'b> with
        member x.AddValidationMethod(methodToAdd:('a -> MethodResult<'b>)) =
          new Validator<'a, 'b>() :> IValidator<'a, 'b>

        member x.Validate(model:'a) =
          (new MethodResult<'b>()).AddErrorMessage("")
    }

    let mainController = new MainController(validatorWithFalseReturn)

(Side note: you might see the :> notation. This is basically the same as (SomeInterface)SomeClass in C#.)

As you can see, I created a new type and set it into the instantiated controller. As you can imagine, you could create a method that takes in a method to set AddValidation to. This has some really great potential like rolling your own mocking system.

So once again F# is looking to be an amazing language.

One thought on “F#: Creating your own mocks using Object Expressions… Wow”

  1. Might a good word for “inline” in typical .NET parlance be “anonymous?” Or, “anonymously?”

Comments are closed.