【问题标题】:Fake DbContext of Entity Framework 4.1 to Test my repositoriesEntity Framework 4.1 的假 DbContext 来测试我的存储库
【发布时间】:2011-08-18 11:52:20
【问题描述】:

我有一个基础存储库,所有实体存储库都继承自该存储库。

在我的睾丸中,我创建了一个 Fake DbContext 和 Fake DbSet 来测试我的存储库,但是在我的 FakeDbContext 中实现某些方法时,我无法实现 IDbContext.Entry 方法:

public class FakeDbContext : IDbContext
{
    private IDbSet<Usuario> _usuario;
    private IDbSet<Atividade> _atividade;
    private IDbSet<Autor> _autor;
    private IDbSet<CategoriaModulo> _categoriaModulo;
    private IDbSet<CategoriaMateria> _categoriaMateria;
    private IDbSet<Site> _site;
    private IDbSet<Modulo> _modulo;
    private IDbSet<Perfil> _perfil;
    private IDbSet<CategoriaGaleriaImagem> _categoriaGaleriaImagem;

    public IDbSet<Usuario> Usuario { get { return _usuario ?? (_usuario = new FakeDbSet<Usuario>()); } set { } }
    public IDbSet<Atividade> Atividade { get { return _atividade ?? (_atividade = new FakeDbSet<Atividade>()); } set { } }
    public IDbSet<Autor> Autor { get { return _autor ?? (_autor = new FakeDbSet<Autor>()); } set { } }
    public IDbSet<CategoriaModulo> CategoriaModulo { get { return _categoriaModulo ?? (_categoriaModulo = new FakeDbSet<CategoriaModulo>()); } set { } }
    public IDbSet<CategoriaMateria> CategoriaMateria { get { return _categoriaMateria ?? (_categoriaMateria = new FakeDbSet<CategoriaMateria>()); } set { } }
    public IDbSet<Site> Site { get { return _site ?? (_site = new FakeDbSet<Site>()); } set { } }
    public IDbSet<Modulo> Modulo { get { return _modulo ?? (_modulo = new FakeDbSet<Modulo>()); } set { } }
    public IDbSet<Perfil> Perfil { get { return _perfil ?? (_perfil = new FakeDbSet<Perfil>()); } set { } }
    public IDbSet<CategoriaGaleriaImagem> CategoriaGaleriaImagem { get { return _categoriaGaleriaImagem ?? (_categoriaGaleriaImagem = new FakeDbSet<CategoriaGaleriaImagem>()); } set { } }

    public void SaveChanges()
    {
        //do nothing
    }

    public IDbSet<TEntity> Set<TEntity>() where TEntity : class
    {
        foreach (PropertyInfo property in typeof(FakeDbContext).GetProperties())
        {
            if (property.PropertyType == typeof(IDbSet<TEntity>))
                return property.GetValue(this, null) as IDbSet<TEntity>;
        }
        throw new Exception("Type collection not found");
    }

    public System.Data.Entity.Infrastructure.DbEntityEntry Entry<TEntity>(TEntity entity) where TEntity : class
    {
    }
}

最后一个我无法实现的方法,你们能帮帮我吗?

我正在使用这个 Entry 方法来更新我的基础存储库中的实体:

public abstract class BaseRepository<TEntity> : IBaseRepository<TEntity> where TEntity : class
    {
        #region Fields

        protected TEntity EntityType;
        protected IDbSet<TEntity> DbSet;

        #endregion

        #region Properties

        public IDbContext DbContext
        {
            get
            {
                return DbContextFactory.Instance.GetOrCreateContext();
            }
        }

        #endregion

        #region Constructors

        protected BaseRepository()
        {
            this.EntityType = DependencyResolverFactory.Instance.Get<TEntity>();
            this.DbSet = DbContext.Set<TEntity>();
        }

        #endregion

        #region Methods

        public virtual void Add(TEntity entity)
        {
            this.DbSet.Add(entity);
        }

        public virtual void Remove(TEntity entity)
        {
            this.DbSet.Remove(entity);
        }

        public virtual void RemoveById(object id)
        {
            TEntity entity = this.GetById(id);
            this.DbSet.Remove(entity);
        }

        public virtual void Edit(TEntity entity)
        {
            this.DbContext.Entry(entity).State = EntityState.Modified;
        }

        public virtual TEntity GetById(object id)
        {
            return (TEntity)this.DbSet.Find(id);
        }

        public virtual IList<TEntity> GetAll()
        {
            return ((IEnumerable<TEntity>)this.DbSet).ToList();
        }

        #endregion
    }

【问题讨论】:

  • 用fake dbContext测试一个repository是什么意思。存储库直接要求 DbContext。您的存储库类中有业务逻辑吗?
  • @Ladislav 在我的存储库中,我没有将 IDbSet 或 IQueryable 暴露给我的控制器,因为那样,我从不在测试中使用 LINQ To 对象,在我的应用程序中使用 LINQ To 实体,所有 LINQ To对象,我的存储库中的方法将谨慎使用 LINQ To Entities。

标签: c# .net unit-testing entity-framework repository


【解决方案1】:

在继续之前阅读this 和所有相关问题。对返回 EF 相关类或使用 linq-to-entities 的任何内容进行单元测试是危险的。

放弃对存储库进行单元测试,而是通过伪造存储库本身来对应用程序逻辑进行单元测试。如果您想测试您的存储库,请创建与真实数据库对话的集成测试。

【讨论】:

  • 但我没有将 IDbSet 或 Iqueryable 暴露给我的控制器。
  • 是的,你没有,但你为什么要伪造上下文?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-20
相关资源
最近更新 更多