X3ntr
X3ntr

Reputation: 155

C# Moq how to setup EF DbContext extension method ToList() to return mock.Object.Tolist()

I'm trying to mock Entity Frameworks DbContext using Moq and in particular its extension methods Add(), Tolist() and Find().

I need the Find() and ToList() methods to actually return values stored in my mockContext.Object.

I've created my DbSet and set following properties:

var mockTickets = new Mock<DbSet<Ticket>>();

mockTickets.As<IQueryable<Ticket>>().Setup(m => m.Provider).Returns(tickets.Provider);
mockTickets.As<IQueryable<Ticket>>().Setup(m => m.Expression).Returns(tickets.Expression);
mockTickets.As<IQueryable<Ticket>>().Setup(m => m.ElementType).Returns(tickets.ElementType);
mockTickets.As<IQueryable<Ticket>>().Setup(m => m.GetEnumerator()).Returns(() => tickets.GetEnumerator());

I've created my DbContext with the following property

var mockContext = new Mock<SupportCenterDbContext>();
mockContext.Setup(m => m.Tickets).Returns(mockTickets.Object);

Now I'm trying to test the following methods

I've tried the following code but get "Invalid setup on an extension method".

mockContext.Setup(x => x.Tickets.Add(It.IsAny<Ticket>())).Returns(It.IsAny<Ticket>());
mockContext.Setup(x => x.Tickets.ToList()).Returns(mockTickets.Object.ToList());
mockContext.Setup(x => x.Tickets.Find(It.IsAny<int>())).Returns(It.IsAny<Ticket>());

These are my assertions for the Add() and ToList() methods

//ToList
Assert.AreEqual(result.Count(), mockContext.Object.Tickets.Count());
Assert.IsInstanceOfType(result, typeof(IEnumerable<Ticket>));

//Add
Assert.IsInstanceOfType(result, typeof(Ticket));
mockContext.Verify(x => x.Tickets.Add(It.IsAny<Ticket>()), Times.Once());
mockContext.Verify(x => x.SaveChanges(), Times.Once());

EDIT
I'm a step closer by removing mockContext.Setup(x => x.Tickets.ToList()).Returns(mockTickets.Object.ToList());.

and adding the following

This last line still doesn't produce the desired output. Is it not possible to pass the value of the input parameter to the Find() method in the Returns() section?

Thanks in advance for any help.

Upvotes: 3

Views: 4423

Answers (1)

Mel Gerats
Mel Gerats

Reputation: 2252

You can't mock extension methods, and it is not a common practice to mock the DBContext.

A better idea would be to use an in-memory data context and populate it with test data, as described here: https://learn.microsoft.com/en-us/ef/core/miscellaneous/testing/in-memory

Upvotes: 2

Related Questions