簡體   English   中英

如何模擬返回的模擬對象的方法?

[英]How can I mock a method of a returned mock object?

我是Moq的新手。 我按照此處提供的指導對實體框架6項目進行單元測試。 所以我有一個模板化的方法來創建假表:

    protected Mock<DbSet<TheType>> MockDBSet<TheType>(List<TheType> data) where TheType : class
    {
        var mockSet = new Mock<DbSet<TheType>>();
        var dataSet = data.AsQueryable();
        mockSet.As<IQueryable<TheType>>().Setup(m => m.Provider).Returns(dataSet.Provider);
        mockSet.As<IQueryable<TheType>>().Setup(m => m.Expression).Returns(dataSet.Expression);
        mockSet.As<IQueryable<TheType>>().Setup(m => m.ElementType).Returns(dataSet.ElementType);
        mockSet.As<IQueryable<TheType>>().Setup(m => m.GetEnumerator()).Returns(dataSet.GetEnumerator());
        mockSet.Setup(x => x.Add(It.IsAny<TheType>()))
            .Returns(new Func<TheType, TheType>(x =>
            {
                data.Add(x);
                return data.Last();
            }));

        return mockSet;
    }

使用上面的工作正常添加和查詢假數據庫:

var db = new Mock<BloggingContext>();
db.Setup(m => m.Blog s).Returns(MockDBSet<Blog >(
    new List<Blog>() 
).Object);

BloggingContext context = db.Object;

Blog blog= new Blog();
context.Blogs.Add(blog); //fine
Assert.IsTrue(context.Blogs.Count() == 1); //fine

EF還在實體集合上提供“本地”屬性,用於訪問未保存的實體。 因此,在不進行模擬時,BloggingContext.Blogs.Local會傳回一個未保存實體的ObservableCollection集合。 調用BloggingContext.SaveChanges()時,對象從BloggingContext.Blogs.Local移動到BloggingContext.Blogs。

我想模仿這種行為,所以我創建了一個新類:

    public class FakeBlogs : List<Blog>
    {
        ObservableCollection<Blog> _local = new ObservableCollection<Blog>();
        ObservableCollection<Blog> Local { get { return _local; } }

        public void Add (Blog item)
        {
            _local.Add(item);
        }
    }

單元測試時,以下代碼有效:

var db = new Mock<BloggingContext>();
db.Setup(m => m.Blog s).Returns(MockDBSet<Blog>(
    new FakeBlogs() //<===== Changed to use FakeBlogs
).Object);

BloggingContext context = db.Object;

Blog blog= new Blog();    
context.Blogs.Add(blog); //fine
Assert.IsTrue(context.Blogs.Count() == 1); //fine

但是,使用Local屬性會拋出NPE,因為Local屬性為null。

var blog = (from i in context.Blogs.Local select i).FirstOrDefault();//throws NPE

如何成功模擬Local屬性?

固定。 我將以下行添加到MockDBSet模板函數中:

        mockSet.Setup(m => m.Local).Returns(data.Local);

並宣布FakeTable的“Local”屬性為public。 感謝所有感興趣的人。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM