Steve Wright
Steve Wright

Reputation: 575

Mocking async methods with optional parameters throws Expression is not a Property Access

I'm using the Nuget package Moq (v4.13.1)

The class/method I'm trying to mock has the following interface:

public interface IAgendaService
{
    Task<IList<IMeeting>> GetRecentMeetingsMostRecentFirstAsync(
        IWho who,
        TimeSpan? timeSpan = null,
        int? maxNumberOfMeetings = null);
}

In my test method I have the following code to define the Mock:

        Mock<IAgendaService> service = new Mock<IAgendaService>(MockBehavior.Strict);

        service.SetupGet(x =>
                x.GetRecentMeetingsMostRecentFirstAsync(
                    It.IsAny<IWho>(),
                    It.IsAny<TimeSpan?>(),
                    It.IsAny<int?>()))
            .Returns(Task.FromResult((IList<IMeeting>)new List<IMeeting>()));

When I run the test, the service.SetupGet() throws the following exception:

Test method Agenda.Web.Tests.Controllers.HomeController.IndexTests.TestIndex threw exception: System.ArgumentException: Expression is not a property access: x => x.GetRecentMeetingsMostRecentFirstAsync(It.IsAny(), It.IsAny(), It.IsAny()) at Moq.ExpressionExtensions.ToPropertyInfo(LambdaExpression expression) at Moq.Mock.SetupGet(Mock mock, LambdaExpression expression, Condition condition) at Moq.Mock1.SetupGet[TProperty](Expression1 expression)

What am I doing wrong?

Upvotes: 1

Views: 940

Answers (1)

Ehsan Sajjad
Ehsan Sajjad

Reputation: 62488

It seems like you are using the wrong method to do the mock setup. You should be using the Setup method as SetupGet is used for property getter. Try following:

service.Setup(x =>
            x.GetRecentMeetingsMostRecentFirstAsync(
                It.IsAny<IWho>(),
                It.IsAny<TimeSpan?>(),
                It.IsAny<int?>()))
        .Returns((IList<IMeeting>)new List<IMeeting>()));

There is also no need to use Task.FromResult as there is nothing async happening as it's a mock object.

Upvotes: 6

Related Questions