Eugen
Eugen

Reputation: 2990

Mock an IList.Add using Moq

I'm trying to setup a moq object to run some unit tests against the business layer object which uses EF6. So far I can test simple methods invocations and check whether those methods were called. But, is there a way to test if an object was actually inserted into the underlying collection.

This is my mock method

private Mock<DbSet<T>> CreateMockDbSet<T>(IQueryable<T> entities) where T : class
{
    var mockSet = new Mock<DbSet<T>>();
    mockSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(entities.Provider);
    mockSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(entities.Expression);
    mockSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(entities.ElementType);
    mockSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(entities.GetEnumerator());
    IList<T> list = entities as IList<T>;
    mockSet.As<IList<T>>().Setup(m => m.Add(It.IsAny<T>())).Returns(list.Add(It.IsAny<T>()));
    mockSet.Setup(m => m.Include(It.IsAny<string>())).Returns(mockSet.Object);
    return mockSet;
}

I'm trying to mock the actual Add method from the list, but as written above is says there is no method .Return.

Is this even possible?

I need to validate if the object was inserted into my mock collection after some logic takes place.

Upvotes: 5

Views: 1776

Answers (1)

Johnny
Johnny

Reputation: 9529

IList.Add method returns void so you cannot setup return, instead of it use .Callback

mockSet.As<IList<T>>()
    .Setup(m => m.Add(It.IsAny<T>()))
    .Callback<T>(item => list.Add(item));

or use Capture.In

mockSet.As<IList<T>>()
    .Setup(m => m.Add(Capture.In(list)));

Upvotes: 6

Related Questions