How to mock LINQ to Entities helpers such as 'SqlFunctions.StringConvert()'

No it is not possible because the function's implementation looks like:

[EdmFunction("SqlServer", "STR")]
public static string StringConvert(decimal? number, int? length)
{
    throw EntityUtil.NotSupported(Strings.ELinq_EdmFunctionDirectCall);
}

You cannot use Moq to fake this function. You need more powerful mocking framework which will allow you replacing static function call - probably Microsoft Fakes, TypeMock Isolator or JustMock.

Or you need to think about your testing approach because mocking the context is the wrong idea. You should instead have something like:

var convertError = myQueryProvider.ConvertQuery(x.convert); 

Where queryProvider will be your mockable type hiding your query. Query is database related logic and it should be tested against the real database. Code around your query is your application logic and it should be unit tested - the best solution to test them both correctly is simply to separate them through some interface (query provider in this case but people often go with a full specific repository). This principle comes from separation of concerns - query execution is separate concern so it is placed into its own method which is tested separately.


What I did was to provide my own implementations of DbFunctions such that LINQ To Objects in a unit test uses a simple .NET implementation and LINQ To EF at runtime uses the DbFunctionAttribute in the same way System.Data.Entity.DbFunctions would. I had thought about mocking DbFunctions but hey, the LINQ to Objects implementations are useful and work fine. Here is an example:

public static class DbFunctions
{
    [DbFunction("Edm", "AddMinutes")]
    public static TimeSpan? AddMinutes(TimeSpan? timeValue, int? addValue)
    {
        return timeValue == null ? (TimeSpan?)null : timeValue.Value.Add(new TimeSpan(0, addValue.Value, 0));
    }
}

You are able to mock EdmFunctions, and I have done this using NSubstitute (which also doesn't support mocking static functions). The trick is to wrap your DbContext in an interface. Then, add your static EdmFunction function to a static class and create an extension method to your context in the static class to call the method. For example

public static class EdmxExtensions
{
   [EdmFunction("SqlServer", "STR")]
   public static string StringConvert(decimal? number, int? length)
   {
      throw EntityUtil.NotSupported(Strings.ELinq_EdmFunctionDirectCall);
   }

   public static IQueryable<Person> MyFunction(this IDbContext context, decimal? number, int? length)
   {
      context.Person.Where(s => StringConvert(s.personId, number, length);
   }

You will then be able to mock MyFunction since it is a method available to an interface, and EntityFramework doesn't get angry when you try to call it.

I have not tried this with Moq, but you may be able to do this in a similar way.