c# – 使用Moq和存储库模式进行单元测试

前端之家收集整理的这篇文章主要介绍了c# – 使用Moq和存储库模式进行单元测试前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我是单元测试的新手,我想要一些帮助.我首先使用存储库模式的代码.我有一个通用的存储库,其中包含称为Generic Repository的通用CRUD操作(请参阅打击)
public abstract class GenericRepository<T> where T : class
    {
        private HolidayDatabaseContext _dataContext;
        private readonly IDbSet<T> _dbset;
        protected GenericRepository(IDbFactory databaseFactory)
        {
            DatabaseFactory = databaseFactory;
            _dbset = DataContext.Set<T>();
        }
        protected IDbFactory DatabaseFactory
        {
            get;
            private set;
        }
        protected HolidayDatabaseContext DataContext
        {
            get { return _dataContext ?? (_dataContext = DatabaseFactory.Get()); }
        }

        public virtual void Add(T entity)
        {
            _dbset.Add(entity);
        }
        public virtual void Update(T entity)
        {
            _dataContext.Entry(entity).State = EntityState.Modified;
        }
        public virtual void Delete(T entity)
        {
            _dbset.Remove(entity);
        }
        public virtual IEnumerable<T> Enumerable()
        {
            return _dbset.AsEnumerable<T>();
        }

        public virtual IQueryable<T> List()
        {
            return _dbset.AsQueryable<T>();
        }

        public virtual T GetSingleById(int id)
        {
            return _dbset.Find(id);
        }

        public void Save()
        {
            _dataContext.SaveChanges();
        }

    }

然后我将其继承到用户存储库并创建了一些特定的方法.见下文

public class UserRepository : GenericRepository<User>,IUserRepository
    {
        public UserRepository(IDbFactory databaseFactory)
            : base(databaseFactory) { }


        public int HolidayEntitlement(int userId)
        {
           return HolidayEntitlement(userId,DateTime.Now);
        }
        public int HolidayEntitlement(int userId,DateTime dateTime)
        {
           //Get the User
            var user = this.GetSingleById(userId);

            //Work Total Entitlement
            int entitlement = user.BaseHolidayEntitlement;

            //Years in Service
            entitlement += (dateTime - user.EmploymentStartDate).Days / 365;

            return entitlement;



        }


         public int RemainingHolidayEntitlement(int userId)
        {
            return RemainingHolidayEntitlement(userId,DateTime.Now);
        }

         public int RemainingHolidayEntitlement(int userId,DateTime dateTime)
        {
            return int.MinValue;
        }
    }

我想单元测试HolidayEntitlement(int userId,DateTime dateTime),但我需要在方法中模拟GetSingleById部分

我把它写成了一个测试,但它没有编译.

[TestMethod]
        public void GetHolidayEntitlement25()
        {
            //How to write this Unit test


            //Setup
            var user = new User { AnnualHolidayIncrement = 1,BaseHolidayEntitlement = 25,EmploymentStartDate = new DateTime(2013,1,1),Id=1 };

            Mock<UserRepository> mock = new Mock<UserRepository>();
            mock.Setup(m => m.GetSingleById(1)).Returns(user);

            Assert.AreEqual(25,mock.Object.HolidayEntitlement(1));
        }

任何帮助,将不胜感激

解决方法

你似乎在说你只想模仿部分界面.当你开始遇到这种情况时,它表明你正在混淆你的担忧,并可能在某处做错事.

在这种情况下,您的存储库正在做的不仅仅是CRUD,因此具有多个职责(它应该只有一个,查找SOLID编程).您正在存储库中执行业务逻辑,它不应该存在!除了简单的CRUD操作之外的任何操作都应该移到业务逻辑层中.即您的HolidayEntitlement方法通过应用某些逻辑来计算某些东西,因此不是CRUD /存储库操作!

所以……你应该做的是将业务逻辑位移到一个新的类中,比如UserLogic.在UserLogic类中,您将使用注入的IUserRepository与存储库进行通信.在UserLogic中,您将放置HolidayEntitlement方法,它将调用IUserRepository.GetSingleById.因此,当您测试UserLogic类时,您将注入具有GetSingleById存根版本的模拟IUserRepository,然后您将返回正确的轨道!

我希望这有道理/有帮助吗?!

– 最后发布 –

附:我的原帖说明你应该模拟接口,而不是实例,所以这仍然适用,我将离开这里作为参考:

你应该模仿IUserRepository NOT UserRepository.

这是因为UserRepository是IUserRepository的一个实现.你想说你给它一个新的实现,即你的模拟.目前您正在使用ACTUAL类UserRepository.

猜你在找的C#相关文章