如何模拟System.Data.Linq.Table <myclass> </myclass>

时间:2010-11-22 18:29:48

标签: .net linq unit-testing mocking moq

我的一个基础存储库类包含一个方法:

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

我正在为包含所述方法的实现的派生存储库类编写单元测试:

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

....
}

此处:上下文 - 是数据库的Linq模型,CMOptions - 数据库表之一。

我希望我的'GetTable()'方法返回一组特殊的数据。

我要模仿这个方法:

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

但不知道如何创建System.Data.Linq.Table<CMCoreDAL.DbData.CMOption>类的实例。

问题:如何模仿System.Data.Linq.Table<>?或者我可能需要更改方法签名以避免System.Data.Linq.Table<>类使用?

请指教。欢迎任何想法。

P.S。我正在使用Moq。

4 个答案:

答案 0 :(得分:7)

如果您使用的是.NET 4.0,Table<T>实现ITable<T>,那么您应该使用返回类型ITable<TDb>中的接口GetTable而不是具体类型。然后你就可以嘲笑了。

在.NET 3.5中,它有点困难,因为Table<T>只实现ITable(非通用)。

答案 1 :(得分:2)

除非明确需要对Table<T>实例执行操作,否则不应将Table<T>暴露在存储库之外。相反,在您的存储库中返回IQueryable<T>,这更容易模拟。如果您需要执行更新,则可以返回ITable<T>

答案 2 :(得分:0)

我想,这是一个解决方案:

  1. 模拟数据上下文:

    IUnityContainer container = new UnityContainer();
    
    Mock<IDataContext> mockDataContext = new Mock<IDataContext>();
    
    container.RegisterInstance(mockDataContext.Object);
    
    CmOptionRepository mockRepository = new CmOptionRepository(container);
    
  2. 模拟返回表:

    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. 模拟'表'对象功能:

    mockTable
        .Setup(mock => mock.Select(
             It.IsAny<Func<CMCoreDAL.DbData.CMOption, ICmOption>>()
        ))
        .Returns(options);
    
  4. 说实话,我不确定它是否有效,明天会检查,但现在它至少已被编译。

答案 3 :(得分:-1)

摘要您的数据访问代码并使用存储库模式。