我有一个以这种方式设置的服务。
public Interface IDataService : IDisposable
{
IQueryable<T> Set<T>() where T : class;
IDbSet<T> WritableSet<T>() where T : class;
}
IDataService 由 DataService 继承。
public abstract class DataService : IDataService
{
public IDataContext DataContext { get; private set; }
public IQueryable<T> Set<T>() where T : class
{
return DataContext.Set<T>().AsNoTracking();
}
public IDbSet<T> WritableSet<T>() where T : class
{
return DataContext.Set<T>();
}
public AddResult<T> Add<T>(T obj) where T : class, IPersistentEntity
{
if (obj == null)
return new AddResult<T>() { IsValid = false };
else
{
if (obj.Id == Guid.Empty)
WritableSet<T>().Add(obj);
bool success = DataContext.SaveChanges() > 0;
return new AddResult<T>() { Entity = obj, IsValid = success };
}
}
}
并且DataService 被EntityService 继承。
public class EntityService : DataService
{
public EntityService(IDataContext DataContext) : base(DataContext)
{
}
public void EntityStarted(Guid Id)
{
var a = GetWriteableById<Entity>(Id);
a.Status = 1;
DataContext.SaveChanges();
}
}
这个 EntityService 用在我的一个组件中。 EntityService 的对象被创建并传递给组件的构造函数。
我正在使用 Moq 对组件执行一些测试,为此,计划是模拟 EntityService,以便 EntityService 使用带有虚拟数据的假数据库容器进行类似数据库的操作。但是,我没有最好的想法用最少的新代码来模拟它。
我所拥有的最不吸引人的想法是使用接口(interface)创建一个假的 EntityService 类,并拥有适合测试的自己的实现。
帮助表示赞赏! :)
最佳答案
根据@JLe 和@Chetan 对该问题的评论,我不得不 mock DbContext。
我按照这篇文章来模拟 DbContext。
Mocking DbContext with Moq
下面是代码的样子。
private void Setup()
{
List<Entity> entityData = new List<Entity>();
entityData.Add(new Entity
{
Id = Guid.NewGuid()
});
DbSet<Entity> MockEntitySet = GetSet(entityData);
MockContext = new Mock<IDbContext>();
MockContext.Setup(m => m.Set<Entity>()).Returns(MockEntitySet);
}
public static DbSet<T> GetSet<T>(List<T> sourceList) where T : class
{
return GetSet(sourceList.ToArray());
}
public static DbSet<T> GetSet<T>(T[] sourceList) where T : class
{
var name = typeof(T).Name;
var queryable = sourceList.AsQueryable();
Mock<DbSet<T>> dbSet = new Mock<DbSet<T>>();
dbSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(queryable.Provider);
dbSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(queryable.Expression);
dbSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(queryable.ElementType);
dbSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(queryable.GetEnumerator());
dbSet.Setup(m => m.AsNoTracking()).Returns(dbSet.Object);
return dbSet.Object;
}
[TestMethod]
public void Test()
{
EntityService service = new EntityService(MockContext.Object);
ComponentToTest compObj = new ComponentToTest(service);
compObj.MethodToTest(...);
// Assertions
}
感谢你们!感谢您的帮助和建议。
关于c# - 在 C# 中使用 Moq 模拟服务,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53755660/