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.