繁体   English   中英

如何检测IDbSet的更改

[英]How can I detect changes IDbSet

我正在创建一个模拟IDbSet,以允许对实体框架类进行单元测试。

但是,我真的很难发现更改,甚至根本不知道该怎么做。 到目前为止,这是我的课程...

public interface IReportContext
{
    IDbSet<Report> Reports {get;}
    public int SaveChanges();
}

public class MockReportContext : IReportContext
{
    IDbSet<Report> Reports {get;}

    public int SaveChanges()
    {
        //Need to detect changes here???
    }

    public MockReportContext()
    {
       Reports = new MockDbSet<Report>();
    }
}

public class MockDbSet<T> : IDbSet<T>
{
    readonly ObservableCollection<T> _data;
    readonly IQueryable _query;

    public FakeDbSet()
    {
        _data = new ObservableCollection<T>();
        _query = _data.AsQueryable();
    }

    public FakeDbSet(ObservableCollection<T> data)
    {
        _data = data;
        _query = _data.AsQueryable();
    }

    public virtual T Find(params object[] keyValues)
    {
        throw new NotImplementedException();
    }

    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();
    }
}

这对于添加,删除和检索实体非常有用。 但是,当我尝试以下操作:

IReportContext context = new MockReportContext();
context.Reports.Add(new Report()); //Works
Report report = context.Reports.First(); //Works
report.Message = "Hello World!";
context.SaveChanges(); //Does nothing

MockReportContext如何知道它返回的报表对象已更改? 我知道使用实体框架可以做到这一点,所以必须做到这一点,但是我不知道如何...

我想您大部分都在那儿,但是我建议您使用Moq (我个人的喜好)或Rhino IReportContext 模拟框架来模拟IReportContext进行单元测试,而不要麻烦创建MockReportContext类的Fake类。 (好的,学习一个模拟框架确实会带来一些麻烦,但是它将节省很多Fake类的繁琐工作。)

我假设您正在对依赖于IReportContext的代码进行单元测试,因此您无需在SaveChanges()内做任何事情,您只需要断言您的代码确实在内部调用了SaveChanges()即可。 。

是将Moq与Entity Framework的派生DbContext / DbSet类一起使用的良好概述

在上面的链接概述中,如果最后的单元测试正在测试内部调用SaveChanges() ,则它还可以通过以下代码行验证您的方法确实调用了SaveChanges()

dc.Verify(db => db.SaveChanges());

您还可以通过在SaveChanges()类中将side属性设置为True并在单元测试结束时对其进行检查,来对MockReportContext类进行此操作, MockReportContext框架更加灵活,可以节省编写其他类的需要用于单元测试。

如果您想避免使用模拟框架,那么这里介绍了如何使用fakes

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM