Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moq Index property Callback with SetupGet

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!

like image 720
tridy Avatar asked Oct 11 '19 09:10

tridy


2 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);
}
like image 57
Nkosi Avatar answered Oct 21 '22 02:10

Nkosi


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);

like image 44
Johnny Avatar answered Oct 21 '22 03:10

Johnny