【问题标题】:Moq - Cannot convert from IGenericRepository To Generic RepositoryMoq - 无法从 IGenericRepository 转换为 Generic Repository
【发布时间】:2018-09-20 21:21:07
【问题描述】:

请见谅,我正在努力学习单元测试和起订量。

我想我几乎已经设法正确设置了(但我可能是错的)。当我执行下面的测试时,出现以下错误:

无法从 'TestMoq.DAL.IGenericRepository' 到 'TestMoq.DAL.GenericRepository' TestMoq.UnitTests

在这一行:

    _mockUnitWork.Setup(m => m.CreditRepository).Returns(_mockRepository.Object);

这是我的代码:

起订量测试

using System;
using NUnit.Framework;
using TestMoq.Controllers;
using TestMoq.Models;
using TestMoq.DAL;
using Moq;
using System.Web.Mvc;
using System.Runtime;
using System.Data.Entity;
using System.Collections.Generic;
using System.Linq;

namespace TestMoq.UnitTests.Controllers
{
    [TestFixture]
    public class BaseControllerTests
    {

        private Mock<IGenericRepository<Credit>> _mockRepository;
        Mock<IUnitOfWork> _mockUnitWork;



        [Test]
        public void MoqTest() {

            _mockRepository = new Mock<IGenericRepository<Credit>>();
            _mockUnitWork = new Mock<IUnitOfWork>();
            var _service = new CreditsController(_mockUnitWork.Object);

            List<Credit> listCredit= new List<Credit>() {
           new Credit() { CreditId = 1},
           new Credit() { CreditId = 2},
           new Credit() { CreditId = 3 }
          };

            _mockRepository.Setup(x => x.Get(null, null, "*")).Returns(listCredit);
            _mockUnitWork.Setup(m => m.CreditRepository).Returns(_mockRepository.Object);

            List<Credit> results = _service.GetAll() as List<Credit>;


            Assert.IsNotNull(results);
            Assert.AreEqual(3, results.Count);
        }
    }
}

CreditController.cs

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using TestMoq.CustomFilters;
using TestMoq.DAL;
using TestMoq.Models;

namespace TestMoq.Controllers
{
    public class CreditsController : Controller
    {
        private UnitOfWork unitOfWork = new UnitOfWork();
        private IUnitOfWork _unitOfWork;

        public CreditsController()
        {
            this._unitOfWork = new UnitOfWork();
        }
        public CreditsController(IUnitOfWork _NewUnitOfWork)
        {
            this._unitOfWork = _NewUnitOfWork;
        }       

        public List<Credit> GetAll()
        {
            return _unitOfWork.CreditRepository.Get().ToList();
        }

    }
}

通用存储库

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Web;
using TestMoq.Models;

namespace TestMoq.DAL
{

    public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class
    {
        internal TcpContext context;
        internal DbSet<TEntity> dbSet;

        public GenericRepository(TcpContext context)
        {
            this.context = context;
            this.dbSet = context.Set<TEntity>();
        }

        public virtual IEnumerable<TEntity> Get(
            Expression<Func<TEntity, bool>> filter = null,
            Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
            string includeProperties = "")
        {
            IQueryable<TEntity> query = dbSet;

            if (filter != null)
            {
                query = query.Where(filter);
            }

            foreach (var includeProperty in includeProperties.Split
                (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
            {
                query = query.Include(includeProperty);
            }

            if (orderBy != null)
            {
                return orderBy(query).ToList();
            }
            else
            {
                return query.ToList();
            }
        }

        public virtual TEntity GetByID(object id)
        {
            return dbSet.Find(id);
        }

        public virtual void Insert(TEntity entity)
        {
            dbSet.Add(entity);
        }

        public virtual void Delete(object id)
        {
            TEntity entityToDelete = dbSet.Find(id);
            Delete(entityToDelete);
        }

        public virtual void Delete(TEntity entityToDelete)
        {
            if (context.Entry(entityToDelete).State == EntityState.Detached)
            {
                dbSet.Attach(entityToDelete);
            }
            dbSet.Remove(entityToDelete);
        }

        public virtual void Update(TEntity entityToUpdate)
        {
            dbSet.Attach(entityToUpdate);
            context.Entry(entityToUpdate).State = EntityState.Modified;
        }
    }
}

IGenericRepository.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace TestMoq.DAL
{
    public interface IGenericRepository<TEntity> where TEntity : class
    {
        void Delete(object id);
        void Delete(TEntity entityToDelete);
        IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, string includeProperties = "");
        TEntity GetByID(object id);
        void Insert(TEntity entity);
        void Update(TEntity entityToUpdate);
    }
}

工作单位

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using TestMoq.Models;

namespace TestMoq.DAL
{

    public class UnitOfWork : IDisposable, IUnitOfWork
    {
        private TcpContext context = new TcpContext();
        public GenericRepository<Credit> creditRepository;

        //Other models & methods removed for clarity


        public GenericRepository<Credit> CreditRepository
        {
            get
            {
                if (this.creditRepository == null)
                {
                    this.creditRepository = new GenericRepository<Credit>(context);
                }

                return creditRepository;
            }

        }

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

    }
}

IUnitOfWork.cs

using TestMoq.Models;

namespace TestMoq.DAL
{
    public interface IUnitOfWork
    {
        GenericRepository<Amendment> AmendmentRepository { get; }
        GenericRepository<Credit> CreditRepository { get; }
        GenericRepository<FileUpload> FileUploadRepository { get; }
        GenericRepository<Job> JobRepository { get; }
        GenericRepository<Subscription> SubscriptionRepository { get; }
        GenericRepository<Topic> TopicRepository { get; }
        GenericRepository<Writer> WriterRepository { get; }

        void Dispose();
        void Save();
    }
}

如果我完全把这件事搞砸了,请提前道歉,如果你发现我的思维方式有任何其他严重错误(我仍然在思考这一切),请向我指出。

谢谢!

【问题讨论】:

  • public GenericRepository&lt;Credit&gt; creditRepository; //Other models &amp; methods removed for clarity public GenericRepository&lt;Credit&gt; CreditRepository 你是说这两个都是IGenericRepository 吗?
  • @mjwills 是正确的。您的IUnitOfWork 几乎可以肯定将存储库属性定义为它们的接口类型,而不是它们的具体类型。 GenericRepository&lt;&gt; 实现IGenericRepository&lt;&gt; 并不意味着IGenericRepository&lt;&gt;GenericRepository&lt;&gt;,因此会出现转换错误。
  • 谢谢!在那个帮助下设法弄清楚了。

标签: c# unit-testing moq


【解决方案1】:

您只能模拟接口 在这种情况下,您需要在 IUnitOfWork 中返回 IGenericRepository。

类似的东西

public interface IUnitOfWork
    {
        IGenericRepository<Amendment> AmendmentRepository { get; }
        IGenericRepository<Credit> CreditRepository { get; }
        IGenericRepository<FileUpload> FileUploadRepository { get; }
        IGenericRepository<Job> JobRepository { get; }
        IGenericRepository<Subscription> SubscriptionRepository { get; }
        IGenericRepository<Topic> TopicRepository { get; }
        IGenericRepository<Writer> WriterRepository { get; }

        void Dispose();
        void Save();
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-06
    • 2019-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多