C# 如何使用moq模拟这些类

C# 如何使用moq模拟这些类,c#,unit-testing,moq,C#,Unit Testing,Moq,请有人告诉我如何正确模拟这个存储库类。基本上,我只想模拟它,以便可以轻松地测试我的服务层。Am moq在我的测试项目中使用c#moq。我遇到的主要问题是查询、筛选、包含和OrderBy方法中使用的虚拟接口模式。我如何模拟它,以便它能够返回我注入到存储库模拟中的正确的RepositoryQuery 下面显示的代码是与数据库通信的数据库层的一部分,因此我想模拟它,以便可以轻松地测试我的服务层,而无需担心外部依赖性 public sealed class RepositoryQuery<TEn

请有人告诉我如何正确模拟这个存储库类。基本上,我只想模拟它,以便可以轻松地测试我的服务层。Am moq在我的测试项目中使用c#moq。我遇到的主要问题是查询、筛选、包含和OrderBy方法中使用的虚拟接口模式。我如何模拟它,以便它能够返回我注入到存储库模拟中的正确的RepositoryQuery

下面显示的代码是与数据库通信的数据库层的一部分,因此我想模拟它,以便可以轻松地测试我的服务层,而无需担心外部依赖性

 public sealed class RepositoryQuery<TEntity> : IRepositoryQuery<TEntity> where TEntity  : BaseEntity
   {

        private readonly List<Expression<Func<TEntity, object>>> _includeProperties;
        private readonly Repository<TEntity> _repository;
        private readonly List<Expression<Func<TEntity, bool>>> _filters;
        private Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> _orderByQuerable;
        private int? _page;
        private int? _pageSize;

        public RepositoryQuery(Repository<TEntity> repository)
        {
            _repository = repository;
            _includeProperties = new List<Expression<Func<TEntity, object>>>();
            _filters = new List<Expression<Func<TEntity, bool>>>();
        }

        public RepositoryQuery<TEntity> Filter(Expression<Func<TEntity, bool>> filter)
        {
            _filters.Add(filter);
            return this;
        }

        public RepositoryQuery<TEntity> OrderBy(Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy)
        {
            _orderByQuerable = orderBy;
            return this;
        }

        public RepositoryQuery<TEntity> Include(Expression<Func<TEntity, object>> expression)
        {
            _includeProperties.Add(expression);
            return this;
        }    

        public IQueryable<TEntity> Get()
        {
            return _repository.Get(_filters, _orderByQuerable, _includeProperties, _page, _pageSize);
        }

    }
公共密封类RepositoryQuery:IRepositoryQuery其中tenty:BaseEntity
{
私有只读列表_包括属性;
私有只读存储库_存储库;
专用只读列表过滤器;
private Func_orderbyquery;
私人网页;
私有int?_页面大小;
公共存储库查询(存储库)
{
_存储库=存储库;
_includeProperties=新列表();
_过滤器=新列表();
}
公共存储查询筛选器(表达式筛选器)
{
_过滤器。添加(过滤器);
归还这个;
}
公共存储查询排序依据(Func排序依据)
{
_orderByQuerable=orderBy;
归还这个;
}
public RepositoryQuery Include(表达式)
{
_includeProperties.Add(表达式);
归还这个;
}    
公共IQueryable Get()
{
return\u repository.Get(\u filters、\u orderbyqueryable、\u includeProperties、\u page、\u pageSize);
}
}
还有这个

public class Repository<TEntity> : IRepository<TEntity> where TEntity : BaseEntity
    {
         private readonly Guid _instanceId;
        private readonly DbSet<TEntity> _dbSet;
        private readonly IDbContext _context; 

        public Repository(IDbContext context)
        {
            _context = context;
            _dbSet = context.Set<TEntity>();
            _instanceId = Guid.NewGuid();
        }

        public virtual IRepositoryQuery<TEntity> Query()
        {
            var repositoryGetFluentHelper = new RepositoryQuery<TEntity>(this);
            return repositoryGetFluentHelper;
        }

        internal IQueryable<TEntity> Get(
            List<Expression<Func<TEntity, bool>>> filters = null,
            Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
            List<Expression<Func<TEntity, object>>> includeProperties = null,
            int? page = null,
            int? pageSize = null)
        {
            IQueryable<TEntity> query = _dbSet;

            if (includeProperties != null)
            {
                includeProperties.ForEach(i => query = query.Include(i));
            }

            if (filters != null && filters.Any())
            {
                query = filters.Aggregate(query, (current, filter) => current.Where(filter));
            }

            query = orderBy != null ? orderBy(query) : query.OrderBy(a => a.Id);

            if (page != null && pageSize != null)
            {
                query = query
                    .Skip((page.Value - 1)*pageSize.Value)
                    .Take(pageSize.Value);
            }
            return query;
        }


    }
公共类存储库:IRepository其中tenty:BaseEntity
{
私有只读Guid\u实例ID;
私有只读数据库集_DbSet;
私有只读IDbContext _context;
公共存储库(IDbContext上下文)
{
_上下文=上下文;
_dbSet=context.Set();
_instanceId=Guid.NewGuid();
}
公共虚拟IRepositoryQuery查询()
{
var repositoryGetFluentHelper=新的RepositoryQuery(this);
返回存储GetFluentHelper;
}
内部易读的获取(
列表筛选器=空,
Func orderBy=null,
列表includeProperties=null,
int?page=null,
int?pageSize=null)
{
IQueryable查询=_dbSet;
if(includeProperties!=null)
{
includeProperties.ForEach(i=>query=query.Include(i));
}
if(filters!=null&&filters.Any())
{
query=filters.Aggregate(query,(current,filter)=>current.Where(filter));
}
query=orderBy!=null?orderBy(query):query.orderBy(a=>a.Id);
if(page!=null&&pageSize!=null)
{
查询=查询
.Skip((page.Value-1)*pageSize.Value)
.Take(pageSize.Value);
}
返回查询;
}
}

希望您的组件依赖于接口
IRepositoryQuery
IRepository
,而不是具体的实现
RepositoryQuery
存储库
。如果是这种情况,那么您可以使用Moq为接口提供双重测试,以便进行单元测试

var mockQuery = new Mock<IRepositoryQuery<TEntity>>();

// perform any setup needed on mockQuery for the particular System Under Test

var mockRepository = new Mock<IRepository<TEntity>>();

// perform any setup needed on mockRepository for the particular System Under Test

// component that relies on query and repository
// that is the System Under Test i.e. the focus of the unit test
var systemUnderTest = new SystemUnderTest(mockRepository.Object, mockQuery.Object);
var mockQuery=new Mock();
//对测试中的特定系统执行mockQuery所需的任何设置
var mockRepository=new Mock();
//为测试中的特定系统在mockRepository上执行所需的任何设置
//依赖于查询和存储库的组件
//这就是被测试的系统,即单元测试的焦点
var systemUnderTest=新的systemUnderTest(mockRepository.Object,mockQuery.Object);

观察;查看
RepositoryQuery
,我认为这些方法应该返回接口
IRepositoryQuery
,而不是具体实现
RepositoryQuery

,如果
IRepositoryQuery
IRepository
的包装器,然后-要测试您的服务层-您不需要模拟
IRepository
。只需模拟
IRepositoryQuery

假设我想检查
SomeService.DoSomething
是否正确处理从
IRepositoryQuery.Get获得的结果:

var mock = new Mock<IRepositoryQuery<SomeClass>>();
mock.Setup(o => o.Get(/* test parameters */)).Returns(/* result */);

var myService = new SomeService(mock.Object);
Assert.That(myService.DoSomething(), Is.EqualTo(/* expected result*/));
var mock=new mock();
mock.Setup(o=>o.Get(/*测试参数*/)。返回(/*结果*/);
var myService=newsomeservice(mock.Object);
Assert.That(myService.DoSomething(),Is.EqualTo(/*预期结果*/);

模拟的内容完全取决于当前运行的测试。那件事我们帮不了你。。这完全取决于你。查阅基本模拟教程,了解人们在每次测试中模拟的内容。例如:您不会为了测试一个功能而模拟整个存储库。您好,上面的一些代码是我在数据层中使用的,因为它与数据存储进行通信,我想完全模拟它,这样我不仅可以测试一个功能,还可以测试我的整个服务层。它们都有接口,但是
RepositoryQuery
存储库紧密耦合,因为它是存储库类的助手,这让我感到困惑。@Cizaphil那么接口是什么样子的呢?