为了账号安全,请及时绑定邮箱和手机立即绑定

在 C# 中使用 Moq 模拟服务

在 C# 中使用 Moq 模拟服务

C#
跃然一笑 2022-06-12 14:47:16
我有一个以这种方式设置的服务。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 使用带有虚拟数据的假数据库容器进行类似数据库的操作。但是,我没有最好的主意用最少的新代码来模拟这个。我拥有的最不吸引人的想法是使用接口创建一个假的 EntityService 类,并拥有适合测试的自己的实现。帮助表示赞赏!:)
查看完整描述

2 回答

?
catspeake

TA贡献1111条经验 获得超0个赞

根据@JLe 和@Chetan 对这个问题的评论,我不得不模拟 DbContext。我按照这篇文章来模拟 DbContext。


使用 Moq 模拟 DbContext


这是代码的样子。


    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

    }

感谢你们!感谢您的帮助和建议。


查看完整回答
反对 回复 2022-06-12
?
GCT1015

TA贡献1827条经验 获得超4个赞

要模拟你需要一个接口,如果没有,你需要将要模拟的方法标记为虚拟。

在幕后,模拟框架将为您创建一个新的实现,其行为与您配置模拟一样。

希望能帮助到你。


查看完整回答
反对 回复 2022-06-12
  • 2 回答
  • 0 关注
  • 289 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号