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.

Combine Lambda Expressions: The And and the Or

Found this post here but wanted to make a really simple example to demonstrate this.

The idea is simple, take something like this:

currentItem => currentItem.BooleanMethodOne() && currentItem.BooleanMethodTwo()

but say you only want to have one clause or both. Well you could make three separate expressions, but what if you wanted to add even more later? What if you wanted to mix and match? What if you’re reading thing because you watched to see what page could possibly be on the last page of a google search? Well I have answers… stolen answers.

First the needed And and Or methods:

public static Expression<Func<T, Boolean>> And<T>(
   Expression<Func<T, Boolean>> expressionOne,
    Expression<Func<T, Boolean>> expressionTwo
)
{
  //Basically this is like a bridge between the two expressions.  It will take the T
  //parameter from expressionOne and apply it to expression two. So if 
  // oneItem => oneItem.OneMethod() is expressionOne
  // twoItem => twoItem.TwoMethod() is expressionTwo
  //it would be like replacing the twoItem with the oneItem so that they now point
  //to the same thing.
  var invokedSecond = Expression.Invoke(expressionTwo, expressionOne.Parameters.Cast<Expression>());

  //Now this is to create the needed expresions to return.  It will take both early expressions
  //and use the item from the first expression in both.
                    
  //It will look something like this:
  //currentItem => (currentItem.OneMethod And Invoke(currentItem => currentItem.TwoMethod()))
  //As you can see, it looks to be running expressionOne and then a new method that basically
  //calls expressionTwo with the same value (currentItem)
  return Expression.Lambda<Func<T, Boolean>>(
   Expression.And(expressionOne.Body, invokedSecond), expressionOne.Parameters
  );
}

public static Expression<Func<T, Boolean>> Or<T>(
Expression<Func<T, Boolean>> expressionOne, 
Expression<Func<T, Boolean>> expressionTwo
)
{
  var invokedSecond = Expression.Invoke(expressionTwo, expressionOne.Parameters.Cast<Expression>());

  return Expression.Lambda<Func<T, Boolean>>(
   Expression.Or(expressionOne.Body, invokedSecond), expressionOne.Parameters
  );
}

And here’s a test for it:

String[] list;

list = new String[] { "a", "b", "c", "ac", "ab", "cc", "d", "dd", "dc" };

Expression<Func<String, Boolean>> stringLikeA = currentString => currentString.Contains("a");
Expression<Func<String, Boolean>> stringLikeB = currentString => currentString.Contains("b");
Expression<Func<String, Boolean>> stringLikeC = currentString => currentString.Contains("c");

Expression<Func<String, Boolean>> neededUser = And<String>(stringLikeA, stringLikeB);
list.Where(neededUser.Compile());

//a
Assert.IsTrue(list.Where(neededUser.Compile()).Count() == 1);  //ab

//a, c, ac, ab, cc, dc
neededUser = Or<String>(stringLikeA, stringLikeC);

Assert.IsTrue(list.Where(neededUser.Compile()).Count() == 6);

//ab, c, ac, cc, dc
neededUser = And<String>(stringLikeA, stringLikeB);
neededUser = Or<String>(neededUser, stringLikeC);
Assert.IsTrue(list.Where(neededUser.Compile()).Count() == 5);

USINGS!!ONEONE

using System;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;

I’m starting to worry about myself

So the “dynamic” linq query so far isn’t just enough to stop. Oh no, now that I can have methods pass back expressions, what about a dictionary of order by expressions to allow an even more dynamic feel? Huh? How’s about that kids? I hate myself too.

//Enum created for the dictionary key
public enum OrderByChoice
{
  FirstName,
  LastName,
  UserName
}

//dictionary of expressions
private static Dictionary<OrderByChoice, Expression<Func<User, String>>>  GetOrderByList()
{
  if(orderByList == null)
  {
    orderByList = new Dictionary<OrderByChoice,Expression<Func<User, String>>>();

    orderByList.Add(OrderByChoice.FirstName, currentUser => currentUser.FirstName);
    orderByList.Add(OrderByChoice.LastName, currentUser => currentUser.LastName);
    orderByList.Add(OrderByChoice.UserName, currentUser => currentUser.UserName);
  }

  return orderByList;
}

That’s right, I know. Silly, but I think it’s cool. Now mind you, I could have methods that return expressions instead of the expressions themselves, but I wanted to show the expressions.

And for the method call:

public static IList<User> GetUserList(OrderByChoice orderBy)
{
  return GetUserList(currentUser => true, GetOrderByList()[orderBy]).ToList();
}

And now you have an even more dynamicish call.

I FORGOT THE USINGS!!!!

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq.Expressions;