簡體   English   中英

我如何使用Moq模擬這些類

[英]How do I mock these classes using moq

請有人告訴我如何正確模擬此存儲庫類。 基本上,我只是想模擬它,以便可以輕松測試服務層。 我的測試項目中使用的是c#moq。 問題最多的是Query,Filter,Include和OrderBy方法中使用的虛擬接口模式。 我如何對其進行模擬,以便它可以返回正確注入到Repository模擬中的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);
        }

    }

和這個

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;
        }


    }

希望您的組件依賴於IRepositoryQuery<TEntity>IRepository<TEntity> ,而不依賴於具體的實現RepositoryQuery<TEntity>Repository<TEntity> 如果是這種情況,那么您可以為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);

觀察; 查看RepositoryQuery<TEntity> ,我認為這些方法應該返回接口IRepositoryQuery<TEntity> ,而不是具體的實現RepositoryQuery<TEntity>

如果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*/));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM