Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架6.1中的模拟DbContext_C#_Entity Framework_Unit Testing_Entity Framework 6_Moq - Fatal编程技术网

C# 实体框架6.1中的模拟DbContext

C# 实体框架6.1中的模拟DbContext,c#,entity-framework,unit-testing,entity-framework-6,moq,C#,Entity Framework,Unit Testing,Entity Framework 6,Moq,我已经找到了一些例子,这些例子(显然)显示了使用EF6模拟DbContext的一个清晰的工作示例,但是,它们似乎都不适合我,我也不完全确定为什么 这是我设置模拟的单元测试代码 var mockData = new List<User> { new User { Email = "my@email.com", Id = 1 } }.AsQueryable(); var mockSet = new Mock<DbSet<User>>(); mockSet

我已经找到了一些例子,这些例子(显然)显示了使用EF6模拟DbContext的一个清晰的工作示例,但是,它们似乎都不适合我,我也不完全确定为什么

这是我设置模拟的单元测试代码

var mockData = new List<User> { new User { Email = "my@email.com", Id = 1 } }.AsQueryable();

var mockSet = new Mock<DbSet<User>>();
    mockSet.As<IQueryable<User>>().Setup(m => m.Provider).Returns(mockData.Provider);
    mockSet.As<IQueryable<User>>().Setup(m => m.Expression).Returns(mockData.Expression);
    mockSet.As<IQueryable<User>>().Setup(m => m.ElementType).Returns(mockData.ElementType);
    mockSet.As<IQueryable<User>>().Setup(m => m.GetEnumerator()).Returns(mockData.GetEnumerator());

    var mockContext = new Mock<MyDbContext>();
    mockContext.Setup(c => c.Users).Returns(mockSet.Object);
这会引发NullReferenceException,因为基础数据库集始终为null。代码执行以下操作:

在基类中

public IEnumerable<T> GetAll()
{
    return _dbSet.AsEnumerable();
}
请注意,虽然有其他问题,因此似乎是相关的,他们不包括EF 6

作为参考,这是一篇MSDN文章,它使用了相同的代码并进行了修改以使其可编译

编辑:

减少了用户服务的复杂性(它使用泛型/接口),代码现在变得简单

public User GetById(int id)
        {
            return _dbContext.Set<User>().FirstOrDefault(x => x.Id == id);
        }
公共用户GetById(int-id)
{
返回_dbContext.Set().FirstOrDefault(x=>x.Id==Id);
}
如果我将此进一步更改为

   var dbSet = _dbContext.Set<User>();
        return dbSet.FirstOrDefault(x => x.Id == id);
var dbSet=_dbContext.Set();
返回dbSet.FirstOrDefault(x=>x.Id==Id);
我可以清楚地看到dbSet是空的

编辑2

根据wablab的建议,mock.Set似乎解决了这个问题

还应归功于Vladyslav Kushnir的DbSet通用方法

为可能需要它的任何人编写的工作代码

 private static Mock<DbSet<T>> GetDbSetMock<T>(IEnumerable<T> items = null) where T : class
        {
            if (items == null)
            {
                items = new T[0];
            }

            var dbSetMock = new Mock<DbSet<T>>();
            var q = dbSetMock.As<IQueryable<T>>();

            q.Setup(x => x.GetEnumerator()).Returns(items.GetEnumerator);

            return dbSetMock;
        }



var mockContext = new Mock<Model1>();

var users = new List<User> { new User { Email = "my@email.com", Id = 1 } };

mockContext.Setup(x => x.Set<User>()).Returns(GetDbSetMock(users).Object);

var service = new UsersService(mockContext.Object);

var user = service.GetById(1);
private static Mock GetDbSetMock(IEnumerable items=null),其中T:class
{
if(items==null)
{
项目=新的T[0];
}
var dbSetMock=new Mock();
var q=dbSetMock.As();
q、 设置(x=>x.GetEnumerator())。返回(items.GetEnumerator);
返回dbSetMock;
}
var mockContext=new Mock();
var users=新列表{新用户{电子邮件=”my@email.com,Id=1};
mockContext.Setup(x=>x.Set()).Returns(GetDbSetMock(users.Object);
var服务=新用户服务(mockContext.Object);
var user=service.GetById(1);
私有Mock GetDbSetMock(IEnumerable items=null),其中T:class
{
if(items==null)
{
项目=新的T[0];
}
var dbSetMock=new Mock();
var q=dbSetMock.As();
q、 设置(x=>x.GetEnumerator())。返回(items.GetEnumerator);
返回dbSetMock;
}
这是我用来模拟DbContext的DbSet的一个非常好用的通用方法。此方法的实际调用是:

var contextMock = new Mock<MyContext>();
contextMock.Setup(x => x.MyDbEntities).Returns(GetDbSetMock<MyDbEntity>().Object);
var contextMock=new Mock();
Setup(x=>x.MyDbEntities).Returns(GetDbSetMock().Object);
私有Mock GetDbSetMock(IEnumerable items=null),其中T:class
{
if(items==null)
{
项目=新的T[0];
}
var dbSetMock=new Mock();
var q=dbSetMock.As();
q、 设置(x=>x.GetEnumerator())。返回(items.GetEnumerator);
返回dbSetMock;
}
这是我用来模拟DbContext的DbSet的一个非常好用的通用方法。此方法的实际调用是:

var contextMock = new Mock<MyContext>();
contextMock.Setup(x => x.MyDbEntities).Returns(GetDbSetMock<MyDbEntity>().Object);
var contextMock=new Mock();
Setup(x=>x.MyDbEntities).Returns(GetDbSetMock().Object);


我认为您需要在
Set()方法上创建一个设置来返回模拟。

我认为您需要在
Set()上创建一个设置
方法返回模拟。

您是否已确认您的
UserService
构造函数正在为传递给
\u dbSet
字段的参数分配
Users
属性?如果这是您的意思,它将不加修改地工作。是从
GetById
方法引发的
NullReferenceException
还是
GetAll
方法?换句话说,是
\u dbSet
为空,还是
\u dbSet.AsEnumerable()的结果为空?(或其他内容是否为空?)已更新,dbSet为空。看起来您需要为返回
mockSet
Set
方法创建一个设置。您是否已确认
UserService
构造函数正在为传递给
\u dbSet
字段的参数分配
Users
属性?如果这是您的意思,它将在未经修改的情况下工作。是吗从
GetById
方法或
GetAll
方法引发的
NullReferenceException
?换句话说,是
\u dbSet
为空,还是
\u dbSet.AsEnumerable()的结果为空?(或者是其他空值?)更新后,dbSet为空。看起来您需要为返回
mockSet
Set
方法创建一个设置。奇怪的是,这在我的机器上不起作用,使用此代码,dbSet仍然为空,不过谢谢。在我的上下文中,我使用的是
IDbSet
而不是
DbSet
试试这个,也许会有帮助。可能这是因为你在模仿DbContext的特定属性,所以你的代码不起作用,当您试图通过
Set
访问数据时,请尝试另外模拟此方法。如何在不使用.Set的情况下拉出DbSet?是的,但我将DbContext(基类),而不是MyDbContext传递给UsersService的构造函数。我甚至把它改成了MyDbContext.Users,它仍然是空的。。。。很奇怪,这在我的机器上不起作用,但是使用这段代码dbset仍然是空的,谢谢。在我的上下文中,我使用的是
IDbSet
,而不是
dbset
,试试看,也许会有帮助。可能这段代码不起作用,因为你在模仿DbContext的特定属性,当您试图通过
Set
访问数据时,请尝试另外模拟此方法。如何在不使用.Set的情况下拉出DbSet?是的,但我将DbContext(基类),而不是MyDbContext传递给UsersService的构造函数。我甚至把它改成了MyDbContext.Users,它仍然是空的。。。。我最后会把这个拿起来的。效果很好。谢天谢地。谢谢
    private Mock<DbSet<T>> GetDbSetMock<T>(IEnumerable<T> items = null) where T : class
    {
        if (items == null)
        {
            items = new T[0];
        }

        var dbSetMock = new Mock<DbSet<T>>();
        var q = dbSetMock.As<IQueryable<T>>();

        q.Setup(x => x.GetEnumerator()).Returns(items.GetEnumerator);

        return dbSetMock;
    }
var contextMock = new Mock<MyContext>();
contextMock.Setup(x => x.MyDbEntities).Returns(GetDbSetMock<MyDbEntity>().Object);