惩戒EF的DbContext与起订量 [英] Mocking EF DbContext with Moq
问题描述
我试图创建我用嘲笑的DbContext服务单元测试。我创建了一个接口 IDbContext
具有以下功能:
公共接口IDbContext :IDisposable的
{
IDbSet< T>设置< T>()其中T:类;
DbEntityEntry< T>进入< T>(T实体),其中T:类;
INT的SaveChanges();
}
我真正的背景下实现了这个接口 IDbContext
和的DbContext
。
现在我试图嘲弄 IDbSet< ; T>
的背景下,因此它返回一个列表<使用者方式>
而不是
[TestMethod的]
公共无效TestGetAllUsers()
{
//安排
变种模拟=新的模拟< IDbContext>();
mock.Setup(X => x.Set<使用者>())
.Returns(新名单<使用者>
{
新用户{ID = 1}
});
UserService userService =新UserService(mock.Object);
//法案
VAR ALLUSERS = userService.GetAllUsers();
//断言
Assert.AreEqual(1,allUsers.Count());
}
我总是得到这个错误 .Returns
:
为
的最佳重载方法匹配'Moq.Language.IReturns< AuthAPI.Repositories .IDbContext,System.Data.Entity.IDbSet< AuthAPI.Models.Entities.User>> .Returns(System.Func< System.Data.Entity.IDbSet< AuthAPI.Models.Entities.User>>)
有一些无效参数
我设法解决它通过创建一个 FakeDbSet< T>
类,它实现 IDbSet< T>
公共类FakeDbSet< T> :IDbSet< T>其中T:类
{
&的ObservableCollection LT; T> _数据;
IQueryable的_query;
公共FakeDbSet()
{
_data =新的ObservableCollection< T>();
_query = _data.AsQueryable();
}
公共虚拟找不到(params对象[]键值)
{
抛出新NotImplementedException(从FakeDbSet<推导; T>并覆盖查找);
}
公众不要再增加(T项目)
{
_data.Add(项目);
回报率的项目;
}
公共t取出(T项目)
{
_data.Remove(项目);
回报率的项目;
}
公共牛逼连接(T项目)
{
_data.Add(项目);
回报率的项目;
}
公共牛逼分离(T项目)
{
_data.Remove(项目);
回报率的项目;
}
公共牛逼的Create()
{
返回Activator.CreateInstance< T>();
}
公共TDerivedEntity创建< TDerivedEntity>()其中TDerivedEntity:类,T
{
返回Activator.CreateInstance< TDerivedEntity>();
}
公众的ObservableCollection< T>当地
{
{返回_data; }
}
型IQueryable.ElementType
{
{返回_query.ElementType; }
}
System.Linq.Expressions.Expression IQueryable.Expression
{
{返回_query.Expression; }
}
IQueryProvider IQueryable.Provider
{
{返回_query.Provider; }
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
返回_data.GetEnumerator();
}
&的IEnumerator LT; T> IEnumerable的< T> .GetEnumerator()
{
返回_data.GetEnumerator();
}
}
现在我的测试是这样的:
[TestMethod的]
公共无效TestGetAllUsers()
{
//安排
变种模拟=新的模拟< IDbContext>();
mock.Setup(X => x.Set<使用者>())
.Returns(新FakeDbSet<使用者>
{
新用户{ID = 1}
});
UserService userService =新UserService(mock.Object);
//法案
VAR ALLUSERS = userService.GetAllUsers();
//断言
Assert.AreEqual(1,allUsers.Count());
}
I'm trying to create a unit test for my service with a mocked DbContext. I created an interface IDbContext
with the following functions:
public interface IDbContext : IDisposable
{
IDbSet<T> Set<T>() where T : class;
DbEntityEntry<T> Entry<T>(T entity) where T : class;
int SaveChanges();
}
My real context implements this interface IDbContext
and DbContext
.
Now I'm trying to mock the IDbSet<T>
in the context, so it returns a List<User>
instead.
[TestMethod]
public void TestGetAllUsers()
{
// Arrange
var mock = new Mock<IDbContext>();
mock.Setup(x => x.Set<User>())
.Returns(new List<User>
{
new User { ID = 1 }
});
UserService userService = new UserService(mock.Object);
// Act
var allUsers = userService.GetAllUsers();
// Assert
Assert.AreEqual(1, allUsers.Count());
}
I always get this error on .Returns
:
The best overloaded method match for
'Moq.Language.IReturns<AuthAPI.Repositories.IDbContext,System.Data.Entity.IDbSet<AuthAPI.Models.Entities.User>>.Returns(System.Func<System.Data.Entity.IDbSet<AuthAPI.Models.Entities.User>>)'
has some invalid arguments
I managed to solve it by creating a FakeDbSet<T>
class that implements IDbSet<T>
public class FakeDbSet<T> : IDbSet<T> where T : class
{
ObservableCollection<T> _data;
IQueryable _query;
public FakeDbSet()
{
_data = new ObservableCollection<T>();
_query = _data.AsQueryable();
}
public virtual T Find(params object[] keyValues)
{
throw new NotImplementedException("Derive from FakeDbSet<T> and override Find");
}
public T Add(T item)
{
_data.Add(item);
return item;
}
public T Remove(T item)
{
_data.Remove(item);
return item;
}
public T Attach(T item)
{
_data.Add(item);
return item;
}
public T Detach(T item)
{
_data.Remove(item);
return item;
}
public T Create()
{
return Activator.CreateInstance<T>();
}
public TDerivedEntity Create<TDerivedEntity>() where TDerivedEntity : class, T
{
return Activator.CreateInstance<TDerivedEntity>();
}
public ObservableCollection<T> Local
{
get { return _data; }
}
Type IQueryable.ElementType
{
get { return _query.ElementType; }
}
System.Linq.Expressions.Expression IQueryable.Expression
{
get { return _query.Expression; }
}
IQueryProvider IQueryable.Provider
{
get { return _query.Provider; }
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return _data.GetEnumerator();
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return _data.GetEnumerator();
}
}
Now my test looks like this:
[TestMethod]
public void TestGetAllUsers()
{
//Arrange
var mock = new Mock<IDbContext>();
mock.Setup(x => x.Set<User>())
.Returns(new FakeDbSet<User>
{
new User { ID = 1 }
});
UserService userService = new UserService(mock.Object);
// Act
var allUsers = userService.GetAllUsers();
// Assert
Assert.AreEqual(1, allUsers.Count());
}
这篇关于惩戒EF的DbContext与起订量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!