Murray
Murray

Reputation: 92

Chaining methods with Moq

I'm attempting to mock and setup chained methods using Moq.

Here is the method I am trying to mock:

TeamMember teamMember = _unitOfWork
    .TeamMembers
    .Query()
    .ToList()
    .Where(t => t.AssociationCode.ToString() == code 
        && Crypto.EncryptStringAES(t.Id.ToString(), sharedSecret) == hash)
    .SingleOrDefault();

and here is where I attempt to mock it:

var unitOfWorkMock = new Mock<IUnitOfWork>();
var iQueryableMock = new Mock<IQueryable<TeamMember>>();
var iToListMock = new Mock<List<TeamMember>>();
var whereMock = new Mock<IList<TeamMember>>();
var singleMock = new Mock<IEnumerable<TeamMember>>();

unitOfWorkMock
    .Setup(u => u.TeamMembers
        .Query())
        .Returns(iQueryableMock.Object);

iQueryableMock
    .Setup(i => i.ToList())
        .Returns(iToListMock.Object); //This line throws the error

whereMock
    .Setup(w =>
            w.Where(It.IsAny<Func<TeamMember, bool>>()))
        .Returns(singleMock.Object);

singleMock
    .Setup(s =>
            s.SingleOrDefault())
        .Returns(new TeamMember()
        {
            Email = "[email protected]"
        });

When I run this test it gives me this error:

Expression references a method that does not belong to the mocked object: i => i.ToList<TeamMember>()

I have looked at this question already and have tried to do something similar, but I must be missing something.

I am new to this, so if anyone can help me out it will be greatly appreciated.

Upvotes: 4

Views: 4096

Answers (1)

Patrick Quirk
Patrick Quirk

Reputation: 23747

Your method chain mocking looks fine, but your problem is that ToList is an extension method, which Moq cannot mock.

Upvotes: 4

Related Questions