我有一个以这种方式设置的服务。

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/

10-10 03:04