How can I mock the returned layout method?

I am new to Moq. I am testing an Entity Framework 6 module following the instructions here . So I have a boilerplate method for creating fake tables:

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

      

Using the above is fine for adding and querying a fake database:

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 also provides a Local property on entity collections that provide access to unoccupied objects. So, when not mocking, BloggingContext.Blogs.Local passes back a collection of ObservableCollection of unsaved objects. Objects are moved from BloggingContext.Blogs.Local to BloggingContext.Blogs when BloggingContext.SaveChanges () is called.

I wanted to mock this behavior, so I created a new class:

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

      

When unit tested, the following code works:

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

      

However, using the Local property throws an NPE because the Local property is null.

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

      

How can I redeem the Local property successfully?

+3


source to share


1 answer


Fixed. I added the following line to the MockDBSet template function:

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

      



And declared the "Local" property FakeTable public. Thanks to everyone who showed interest.

+1


source







All Articles