Moq Index property Callback with SetupGet

Viewed 929

I am trying to write a test for an extension method that adds a prefix for a key that gets sent to the index property of IConfiguration:

extension:

public static class IConfigurationExt
{
    public static string GetDomainValue(this IConfiguration configuration, string key)
    {
        return configuration["domain." + key];
    }
}

test:

[Test]
public void GetInexKeyAsCallback()
{
    string keySet = null;

    Mock<IConfiguration> configurationMock = new Mock<IConfiguration>(MockBehavior.Strict);

    configurationMock.SetupGet(p => p[It.IsAny<string>()])
                        .Callback(() => keySet = "assign key here") // <<< the part here needs the parameter
                        .Returns("mock");

    IConfiguration configuration = configurationMock.Object;

    var result = configuration.GetDomainValue("testKey");

    Assert.AreEqual(expected: "domain.testKey", actual: keySet);
}

I am trying to see that when a getter is executed and a key is sent, it will come with the prefix to the index property of IConfiguration. My problem is that I cannot make the Callback part working with a parameter , such as: .Callback<string>((key) => keySet = key), for example.

Is there a way of getting the key that was sent to the indexed property? It works with SetupSet, but not with SetupGet

Thanks!

3 Answers

SetupGet does not have a Callback that allows access to the passed parameter.

Use Setup instead and then the Callback can access the passed argument by including a parameter in the delegate

public void GetInexKeyAsCallback() {
    //Arrange
    string actual = null;
    string expected = "domain.testKey";

    Mock<IConfiguration> configurationMock = new Mock<IConfiguration>(MockBehavior.Strict);

    configurationMock
        .Setup(_ => _[It.IsAny<string>()]) // <-- Use Setup
        .Callback((string arg) => actual = arg) // <<< the part here gets the parameter
        .Returns("mock");

    IConfiguration configuration = configurationMock.Object;

    //Act
    var result = configuration.GetDomainValue("testKey");

    //Assert
    Assert.AreEqual(expected, actual);
}

Although you already have an answer I would like to suggest the other approach which IMO fits beter in the problem you have described.

I am trying to see that when a getter is executed and a key is sent, it will come with the prefix to the index property of IConfiguration.

The Verify is ment to be used for such a scenario instead of Callback. You could rewrite your test to something like this:

// Arrange
const string expectedKey = "testKey";
Mock<IConfiguration> configurationMock = new Mock<IConfiguration>(MockBehavior.Strict);
configurationMock.SetupGet(p => p[It.IsAny<string>()]).Returns("mock");

// Act
_ = configurationMock.Object.GetDomainValue(expectedKey);

// Assert
configurationMock.Verify(m => m[$"domain.{expectedKey}"], Times.Once);

From memory you need to change

Callback(() =>

to

Callback<string>( x =>
Related