SvenAelterman
SvenAelterman

Reputation: 1662

LINQ to Mocks: accessing method parameters

New to the Moq library, I decided to use LINQ to set up the mocks. I have seen plenty of samples that explain how a method's parameter values can be accessed using .Returns when using the "traditional" method of setting up a mock.

But how do you do it with LINQ to Mocks? My code is below which doesn't run, because I can't find a way to name val. val is supposed to be the value of the second parameter. (UpdatedValue is a variable local to the unit test.)

IAppSettingLogic MoqAsl = Mock.Of<IAppSettingLogic>(asl => 
    asl.SetAppSettingAsync(AppSettings.LatestReconciliationValue, It.IsAny<string>(), It.IsAny<string>()) ==
    Task.Run(() => UpdatedValue = val));

Upvotes: 2

Views: 435

Answers (1)

Nkosi
Nkosi

Reputation: 247551

For complex scenarios like what you describe, the traditional format is usually used as the linq to mock was more for simple quick setup. Linq to mock does not allow access to parameter values

var UpdateValue = string.Empty;

var mock = new Mock<IAppSettingLogic>();
mock
    .Setup(_ => _.SetAppSettingAsync(AppSettings.LatestReconciliationValue, It.IsAny<string>(), It.IsAny<string>())
    .Returns( (string arg0, string val, string args3) => {
        UpdatedValue = val;
        return Task.CompletedTask;
    });

IAppSettingLogic MoqAsl = mock.Object;

LINQ to Mocks is great for quickly stubbing out dependencies that typically don't need further verification. If you do need to verify later some invocation on those mocks, you can easily retrieve them with Mock.Get(instance)

Reference Quickstart: LINQ to Mocks

If you have simple members that can be mocked up quicly you can mix the two formats

//Ling to Mock
IAppSettingLogic MoqAsl = Mock.Of<IAppSettingLogic>(asl => asl.SimpleMember == someSimpleValue);

//Add traditional setup to get access to return function using "Mock.Get(T)"
Mock.Get(MoqAsl)
    .Setup(_ => _.SetAppSettingAsync(AppSettings.LatestReconciliationValue, It.IsAny<string>(), It.IsAny<string>())
    .Returns( (string arg0, string val, string args3) => {
        UpdatedValue = val;
        return Task.CompletedTask;
    });

Upvotes: 3

Related Questions