Budda
Budda

Reputation: 18353

How to mock System.Data.Linq.Table<MyClass>

One of my base repository classes contains a method:

public abstract class RepositoryBase<T, TDb> : IRepository<T>
    where T : IEntity
    where TDb : class, IDbEntity, new()
{
    protected internal abstract Table<TDb> GetTable();
    ...
}

I am writing unit test for derived repository class that contains implementation of mentioned method:

public class CmOptionRepository : 
    RepositoryBase<ICmOption, CMCoreDAL.DbData.CMOption>, ICmOptionRepository
{
    protected internal override System.Data.Linq.Table<CMCoreDAL.DbData.CMOption>
        GetTable()
    {
        return Context.CMOptions;
    }

....
}

Here: Context - is Linq-model of DB, CMOptions - one of the DB tables.

I want my 'GetTable()' method returning a special set of data.

I am going to mock the method:

        System.Data.Linq.Table<CMCoreDAL.DbData.CMOption> table = ...;
        Mock<CmOptionRepository> mockRepository =
            new Mock<CmOptionRepository>(MockBehavior.Strict);
        mockRepository.Setup(mock => mock.GetTable()).Returns(table);

But don't know how to create an instance of System.Data.Linq.Table<CMCoreDAL.DbData.CMOption> class.

Question: how can I mock the System.Data.Linq.Table<>? Or probably I need to change method signature in order to avoid System.Data.Linq.Table<> class usage?

Please advise. Any thoughts are welcome.

P.S. I am using Moq.

Upvotes: 9

Views: 4549

Answers (4)

Budda
Budda

Reputation: 18353

I guess, here is a solution:

  1. Mock data context:

    IUnityContainer container = new UnityContainer();
    
    Mock<IDataContext> mockDataContext = new Mock<IDataContext>();
    
    container.RegisterInstance(mockDataContext.Object);
    
    CmOptionRepository mockRepository = new CmOptionRepository(container);
    
  2. Mock returning table:

    Mock<System.Data.Linq.Table<CMCoreDAL.DbData.CMOption>> mockTable = new Mock<System.Data.Linq.Table<CMCoreDAL.DbData.CMOption>>();
    
    mockDataContext.Setup(mock => mock.CMOptions).Returns(mockTable.Object);
    
  3. Mock 'table' object functionality:

    mockTable
        .Setup(mock => mock.Select(
             It.IsAny<Func<CMCoreDAL.DbData.CMOption, ICmOption>>()
        ))
        .Returns(options);
    

To be honest, I not sure if it will works, will check tomorrow, but now it is at least been compiled.

Upvotes: 0

kburnell
kburnell

Reputation: 57

Abstract away your data access code and use the repository pattern.

Upvotes: -2

Matthew Abbott
Matthew Abbott

Reputation: 61617

You shouldn't really expose Table<T> outside of your repository unless there is an explicit need to perform operations on the Table<T> instance. Instead, return IQueryable<T> in your repository, which is easier to mock. If you need to perform updates then you can return ITable<T>.

Upvotes: 2

jason
jason

Reputation: 241779

If you are using .NET 4.0, Table<T> implements ITable<T> so that you should use the interface ITable<TDb> in the return type of GetTable instead of the concrete type. Then you can mock away.

In .NET 3.5 it is a little more difficult because Table<T> only implements ITable (not generic).

Upvotes: 7

Related Questions