Question

Been busting my head on this one - time to give it up to the crowd: anyone know how to successfully set a Mole (or any other unit testing work around) for a Join in Linq?

Specifically, this particular project is using Linq to Sql. In fact, it is the first time I've used Linq to Sql and I'm trying to demonstrate effective and correct unit testing. I have a method that pulls TableA and TableB, which are linked by a foreign key, to create a data transfer object basically modeled on TableA. Code is in-exact, as I had to leave it at work.

public List<TableADto> GetTableA()
{
    using (MyDataContext context = new MyDataContext)
    {
        var query = from a in context.a
                join b in context.b on a.ForeignId equals b.ForeignId
                select MyBuilderClass.CreateTableADto(a, b);

        return query.ToList();
    }
}

I find the code to be quite elegant in its way, and it works beautifully in system testing. But I can't figure out how to unit test it. I've a veteran user of Moles for setting up detours. For a query from a single table, I can simply put a mole on

System.Linq.Data.Moles.MTable<TableA>.AllInstances.GetEnumerator = ...

For multiple tables, I find that I also need to create a stub IQueryProvider, and I need to stub out the CreateQuery methods. But even doing so, I also get an error message saying that CreateExpression is not stubbed. I've tried

  • MTable<TableA>.AllInstances.CreateQueryExpression = (Expression e) => { return listA.AsQueryable().Provider; }
  • MTable<TableA>.AllInstances.CreateQueryExpression01(Expression e => listA.AsQueryable().Provider; }
  • MTable<TableA>.AllInstances.CreateQueryExpression<TableB> = (Expresion e) => { return listB.AsQueryable().Provider; }
  • // MTable<TableA>.AllInstances.CreateQueryExpression<Tablea> = (Expresion e) => { return listA.AsQueryable().Provider; } /* REDUNDANT WITH THE FIRST ONE */
Was it helpful?

Solution

Here's the solution: MTable can be instantiated. That helps immensely. I needed to set a stub on two different methods for each of my types. Following code worked perfectly:

// Note: typeAList = List<TypeA> with values populated in the test itself

System.Data.Linq.Moles.MTable<TypeA> typeATable = new System.Data.Linq.Moles.MTable<TypeA>();
typeATable.Bind(typeAList);
typeATable.ProviderSystemLinqIQueryableget = () => typeAList.AsQueryable().Provider;
typeATable.ExpressionSystemLinqIQueryableget = () => typeAList.AsQueryable().Expression;
MyLibrary.Data.Moles.MMyDataContext.AllInstances.TypeAsGet = (c) => { return typeATable; };

System.Data.Linq.Moles.MTable<TypeB> typeBTable = new System.Data.Linq.Moles.MTable<TypeB>();
typeBTable.Bind(typeBList);
typeBTable.ProviderSystemLinqIQueryableget = () => typeBList.AsQueryable().Provider;
typeBTable.ExpressionSystemLinqIQueryableget = () => typeBList.AsQueryable().Expression;
MyLibrary.Data.Moles.MMyDataContext.AllInstances.TypeBsGet = (c) => { return typeBTable; };
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top