有没有一种方法可以用Moq来模拟DbSet.Find方法? [英] Is there a way to generically mock the DbSet.Find method with Moq?

查看:52
本文介绍了有没有一种方法可以用Moq来模拟DbSet.Find方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在使用扩展方法来将DbSet作为列表进行模拟:

I'm currently using an extension method to generically mock DbSets as a list:

    public static DbSet<T> AsDbSet<T>(this List<T> sourceList) where T : class
    {
        var queryable = sourceList.AsQueryable();
        var mockDbSet = new Mock<DbSet<T>>();
        mockDbSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(queryable.Provider);
        mockDbSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(queryable.Expression);
        mockDbSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(queryable.ElementType);
        mockDbSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(queryable.GetEnumerator());
        mockDbSet.Setup(x => x.Add(It.IsAny<T>())).Callback<T>(sourceList.Add);
        mockDbSet.Setup(x => x.Remove(It.IsAny<T>())).Returns<T>(x => { if (sourceList.Remove(x)) return x; else return null; } );

        return mockDbSet.Object;
    }

但是,我找不到一种模拟Find方法的方法,该方法基于表的主键进行搜索.我可以在每个表的特定级别上执行此操作,因为我可以检查数据库,获取PK,然后仅模拟该字段的Find方法.但是我不能使用通用方法.

However, I can't figure out a way to mock the Find method, which searches based on the table's primary key. I could do it at a specific level for each table because I can inspect the database, get the PK, and then just mock the Find method for that field. But then I can't use the generic method.

我想我也可以添加到EF自动生成的部分类中,以标记哪个字段是带有属性或某些内容的PK.但是我们有100多个表,如果您依靠人们手动维护此代码,那么它将使代码的管理更加困难.

I suppose I could also go add to the partial classes that EF auto-generated to mark which field is the PK with an attribute or something. But we have over 100 tables and it makes the code more difficult to manage if you're relying on people to manually maintain this.

EF6提供任何查找主键的方法,还是仅在连接到数据库后才动态知道?

Does EF6 provide any way of finding the primary key, or does it only know dynamically after it's connected to the database?

推荐答案

经过一段时间的思考,我认为我找到了当前可用的最佳"解决方案.我只是有一系列的if语句,它们直接检查扩展方法中的类型.然后,我强制转换为需要设置查找行为的类型,并在完成后将其强制转换为泛型.它只是伪通用的,但我想不出其他更好的方法.

After pondering this for awhile, I think I've found the "best" solution currently available. I just have a series of if statements that directly checks the type in the extension method. Then I cast to the type I need to set the find behavior and cast it back to generic when I'm done. It's only pseudo-generic, but I can't think of anything else better.

        if (typeof(T) == typeof(MyFirstSet))
        {
            mockDbSet.Setup(x => x.Find(It.IsAny<object[]>())).Returns<object[]>(x => (sourceList as List<MyFirstSet>).FirstOrDefault(y => y.MyFirstSetKey == (Guid)x[0]) as T);
        }
        else if (typeof(T) == typeof(MySecondSet))
        {
            mockDbSet.Setup(x => x.Find(It.IsAny<object[]>())).Returns<object[]>(x => (sourceList as List<MySecondSet>).FirstOrDefault(y => y.MySecondSetKey == (Guid)x[0]) as T);
        }
        ...       

这篇关于有没有一种方法可以用Moq来模拟DbSet.Find方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆