Soufien Hajji
Soufien Hajji

Reputation: 497

How to moq Linq extension methods

I'm trying to moq an object in which it will be requerable in my test class. I couldn't do it because apperently moq dosen't moq static methods.

    var mockConfiguration = new Mock<IConfiguration>();
    mockConfiguration.Setup(f => f.AsEnumerable()
                                      .Where(kvp => kvp.Key.StartsWith($"CheckerConfigurations:{nameof(OSVersionChecker)}:SupportedVersions:") && kvp.Value != null)
                                      .Select(kvp => kvp.Value)).Returns(new List<string>() {
                                          "Android 5",
                                          "Android 6",
                                          "Darwin Kernel Version 15",
                                          "Darwin Kernel Version 16",
                                          "Windows 10",
                                          "Windows 6.2",
                                          "Windows 6.3"
                                      }.AsEnumerable());

Can anyone show me how to do it please ?

Upvotes: 1

Views: 932

Answers (1)

Oliver
Oliver

Reputation: 45101

You can't mock static methods and so all LINQ methods are not (easy) mockable (in fact it is possible, due to ordering of namespaces and which extension method will be picked), but that is not what you like to do.

Instead you should create an instance (regardless if mocked or real) which provides the desired data and inject this into the methods you like to test.

In case of IConfiguration there is even no mock needed. You can use an existing implementation that provides the desired data.

So for your case i would use the following one:

[Fact]
public void ConfigurationContainsSupportedVersions()
{
    var config = CreateConfiguration();
    var items = config.GetSection($"CheckerConfigurations:{nameof(OSVersionChecker)}:SupportedVersions").Get<List<string>>();

    Assert.Equal(7, items.Count);
}

private static IConfiguration CreateConfiguration()
{
    return new ConfigurationBuilder()
        .AddInMemoryCollection(new Dictionary<string, string>
        {
        { $"CheckerConfigurations:{nameof(OSVersionChecker)}:SupportedVersions:0", "Android 5" },
        { $"CheckerConfigurations:{nameof(OSVersionChecker)}:SupportedVersions:1", "Android 6" },
        { $"CheckerConfigurations:{nameof(OSVersionChecker)}:SupportedVersions:2", "Darwin Kernel Version 15" },
        { $"CheckerConfigurations:{nameof(OSVersionChecker)}:SupportedVersions:3", "Darwin Kernel Version 16" },
        { $"CheckerConfigurations:{nameof(OSVersionChecker)}:SupportedVersions:4", "Windows 10" },
        { $"CheckerConfigurations:{nameof(OSVersionChecker)}:SupportedVersions:5", "Windows 6.2" },
        { $"CheckerConfigurations:{nameof(OSVersionChecker)}:SupportedVersions:6", "Windows 6.3" },
        })
        .Build();
}

This config instance can be forwarded to any method that consumes an IConfiguration and it produces the desired output you like.

Upvotes: 2

Related Questions