将 AddOrUpdate 与 Entity Framework 6 Repository 一起使用的单元测试方法

Posted

技术标签:

【中文标题】将 AddOrUpdate 与 Entity Framework 6 Repository 一起使用的单元测试方法【英文标题】:Unit testing methods using AddOrUpdate with Entity Framework 6 Repository 【发布时间】:2016-05-23 09:24:21 【问题描述】:

我设法模拟了一个实体框架 dbcontext 和 dbset,以允许对存储库组件的查询功能进行单元测试。

我无法使用实体框架的 AddOrUpdate() 方法对 a 方法执行成功的测试。收到的错误是:

“无法在派生的 IDbSet 类型 'Castle.Proxies.DbSet`1Proxy' 上调用公共实例方法 AddOrUpdate。找不到方法。”

是否有可能对此进行测试?

    private IRepository _Sut;
    private Mock<DbSet<JobListing>> _DbSet;
    private Mock<RecruitmentDb> _DbContext;

    [SetUp]
    public void Setup()
    
        _DbContext = new Mock<RecruitmentDb>();

        var JobsData = GenerateJobs().AsQueryable();

        _DbSet = new Mock<DbSet<JobListing>>();
        _DbSet.As<IQueryable<JobListing>>().Setup(x => x.Provider).Returns(JobsData.Provider);
        _DbSet.As<IQueryable<JobListing>>().Setup(x => x.Expression).Returns(JobsData.Expression);
        _DbSet.As<IQueryable<JobListing>>().Setup(x => x.ElementType).Returns(JobsData.ElementType);
        _DbSet.As<IQueryable<JobListing>>().Setup(x => x.GetEnumerator()).Returns(JobsData.GetEnumerator());

        _DbContext.Setup(x => x.JobListings).Returns(_DbSet.Object);
        _Sut = new JobListingRepository(_DbContext.Object);
    

    [Test]
    public void Update_ChangedTitleProperty_UpdatedDetails()
    
        var Actual = GenerateJobs().First();
        var OriginalJob = Actual;
        Actual.Title = "Newly Changed Title";
        _Sut.Update(Actual);

        Actual.Title.Should().NotBe(OriginalJob.Title);
        Actual.Id.Should().Be(OriginalJob.Id);
    

    private List<JobListing> GenerateJobs()
    
        return new List<JobListing>
        
            new JobListing Id = 1,
            Title = "Software Developer",
            ShortDescription = "This is the short description",
            FullDescription = "This is the long description",
            Applicants = new List<Applicant>(),
            ClosingDate = DateTime.Now.AddMonths(5).Date,

            new JobListing
            Id = 2,
            Title = "Head Chef",
            ShortDescription = "This is the short description",
            FullDescription = "This is the long description",
            Applicants = new List<Applicant>(),
            ClosingDate = DateTime.Now.AddMonths(2).Date
            ,

            new JobListing
        
            Id = 3,
            Title = "Chief Minister",
            ShortDescription = "This is the short description",
            FullDescription = "This is the long description",
            Applicants = new List<Applicant>(),
            ClosingDate = DateTime.Now.AddMonths(2).Date
        
        ;
    

【问题讨论】:

我在你的代码中没有看到AddOrUpdate 但这可能与AddOrUpdate是一种扩展方法有关。 AddOrUpdate 在具体的 JobListingRepository 中使用。您如何使用扩展方法执行测试? 如果是这个问题,this 将是重复的。 【参考方案1】:

问题是因为 AddOrUpdate 是一种扩展方法。我通过设计一个包装器克服了这个问题。您可以改为模拟/存根 IAddOrUpdateHelper 接口。

    public class AddOrUpdateHelper : IAddOrUpdateHelper
    

        public void AddOrUpdateEntity<TEntity>(DataContext db, params TEntity[] entities) where TEntity : class
        
            db.Set<TEntity>().AddOrUpdate(entities);
        
    

    public interface IAddOrUpdateHelper
    
        void AddOrUpdateEntity<TEntity>(DataContext db, params TEntity[] entities) where TEntity : class;
    

【讨论】:

很好的答案,不过,您很可能是指“DbContext”而不是“DataContext”。 复制粘贴的危害 @GregRTaylor 我试图遵循这个建议,但是得到了例外:Unable to call public, instance method AddOrUpdate on derived IDbSet&lt;T&gt; type 'Castle.Proxies.DbSet1Proxy'. Method not found.

以上是关于将 AddOrUpdate 与 Entity Framework 6 Repository 一起使用的单元测试方法的主要内容,如果未能解决你的问题,请参考以下文章

解决org.hibernate.HibernateException: identifier of an instance of com.ahd.entity.Order was altered fr

AddOrUpdate 违反唯一索引

csharp 实现.AddOrUpdate也支持nullables

csharp 字典扩展 - GetOrAdd,AddOrUpdate

如何在 EF 4.3 中使用带有复杂键的 AddOrUpdate 播种数据

有没有办法让 DbSet.AddOrUpdate 区分大小写?