George
George

Reputation: 11

Mock issue - Value cannot be null. (Parameter 'source')

I am trying to test an API service using Moq and am getting the error message:

Value cannot be null. (Parameter 'source').

Below is the code [Which is already working fine in the real world, the Mock is a retrospective project.]

models = new List<MyModel> {
    new MyModel
    {
    Id = 1,
    Name = "John Smith",
    Status = "Engineer",
    Centre = 9999
    },
    new MyModel
    {
    Id = 2,
    Name = "Jane Doe",
    Status = "Manager",
    Centre = 9999
    } };

var mockDbSet = new Mock<DbSet<MyModel>>();
mockDbSet.As<IQueryable<MyModel>>().Setup(m => m.Provider).Returns(models.AsQueryable().Provider);
mockDbSet.As<IQueryable<MyModel>>().Setup(m => m.Expression).Returns(models.AsQueryable().Expression);
mockDbSet.As<IQueryable<MyModel>>().Setup(m => m.ElementType).Returns(models.AsQueryable().ElementType);
mockDbSet.As<IQueryable<MyModel>>().Setup(m => m.GetEnumerator()).Returns(models.GetEnumerator());
mockDbSet.Setup(m => m.Add(It.IsAny<MyModel>())).Callback<MyModel>(models.Add);

mockContext = new Mock<LiveDbContext>();
mockContext.Setup(m => m.Add(models)).Callback<DbSet<MyModel>>(mockDbSet.Object.AddRange);

myService = new LiveService(mockContext.Object);            
var result = myService.GetStaffByCentre(9999).Result.ToList();

//Assert
Assert.AreEqual(1, result.Count);            

The line that appears to be causing the error is the

var result = myService.GetStaffByCentre(9999).Result.ToList();

Upvotes: 0

Views: 1562

Answers (2)

George
George

Reputation: 11

Just to give an update, and perhaps help others in the same situation. I realised that I needed to add a Repository layer and create a mock of it in order to create and run Unit Tests.

The Mock repository used the 'models' list [see original post] as its data source which meant I could remove the need to create a 'Mock Context' object and a mock DbSet.

I found this tutorial very helpful.

Upvotes: 1

rgvlee
rgvlee

Reputation: 3213

We don't really know what your service/SUT is doing because you haven't provided it, but I assume it performs a query on the DbSet<MyModel> and returns the unresolved enumerable as the Result member. If that is the case, the ToList() invocation is where the exception will be occurring, when the enumerable is resolved.

Before we go further, my first question would be can you use the in-memory database provider. Mocking EFCore is hard and Microsoft doesn't recommend it.

If there is a reason you can't use the in-memory database provider, and my assumptions are correct, this is probably occurring because you haven't set up the query provider methods such as CreateQuery and Execute which are used by LINQ extensions. Exactly which you need to mock again I can't say, I don't have enough detail.

Upvotes: 0

Related Questions