我的一个基础存储库类包含一个方法:
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。
答案 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)
我想,这是一个解决方案:
模拟数据上下文:
IUnityContainer container = new UnityContainer();
Mock<IDataContext> mockDataContext = new Mock<IDataContext>();
container.RegisterInstance(mockDataContext.Object);
CmOptionRepository mockRepository = new CmOptionRepository(container);
模拟返回表:
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);
模拟'表'对象功能:
mockTable
.Setup(mock => mock.Select(
It.IsAny<Func<CMCoreDAL.DbData.CMOption, ICmOption>>()
))
.Returns(options);
说实话,我不确定它是否有效,明天会检查,但现在它至少已被编译。
答案 3 :(得分:-1)
摘要您的数据访问代码并使用存储库模式。