Unit testing extension method adding view location expander Introduction

I'm writing unit tests for an extension method I wrote. Its only purpose it is to wrap startup logic which extends ViewLocationExpanders list by an instance implementating IViewLocationExpander. ViewLocationExpanders is a property of RazorViewEngineOptions, which can be configured in application startup in ConfigureServices() method. I'm using XUnit 2.4.1.

Usage

Instead of:

services.Configure&lt;RazorViewEngineOptions&gt;(options =&gt;
{
    options.ViewLocationExpanders.Add(new ViewLocationExpander());
});


I can use:

services.AddViewLocationExpander(new ViewLocationExpander());


ViewLocationExpander

public class ViewLocationExpander : IViewLocationExpander
{
    public IEnumerable&lt;string&gt; ExpandViewLocations(
        ViewLocationExpanderContext context, 
        IEnumerable&lt;string&gt; viewLocations)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        if (viewLocations == null)
        {
            throw new ArgumentNullException(nameof(viewLocations));
        }

        /*
            * Note:
            * {0} = action name
            * {1} = controller name
            * {2} = area name
            */

        var newViewLocations = new string[]
        {
            // Example: '/Views/Home/_Partials/FooBar.cshtml'
            "/Views/{1}/_Partials/{0}.cshtml",
        };

        // Add new locations *AFTER* MVC default locations.
        return viewLocations.Union(newViewLocations);
    }

    public void PopulateValues(ViewLocationExpanderContext context)
    {
        context.Values["customviewlocation"] = nameof(ViewLocationExpander);
    }
}


Extension method

public static IServiceCollection AddViewLocationExpander(
    this IServiceCollection services, 
    IViewLocationExpander viewLocationExpander)
{
    if (services == null)
    {
        throw new ArgumentNullException(nameof(services));
    }

    if (viewLocationExpander == null)
    {
        throw new ArgumentNullException(nameof(viewLocationExpander));
    }

    return services.Configure&lt;RazorViewEngineOptions&gt;(options =&gt;
    {
        options.ViewLocationExpanders.Add(viewLocationExpander);
    });
}


Unit tests

[Fact]
public void ExtensionMethodAddsNewViewLocationExpander()
{
    // Arrange
    var services = new ServiceCollection();
    services.AddMvc();

    // These two are required to active the RazorViewEngineOptions.
    services.AddSingleton&lt;IHostingEnvironment, HostingEnvironment&gt;();
    services.AddSingleton&lt;ILoggerFactory, LoggerFactory&gt;();

    // Act
    var serviceProvider = services.BuildServiceProvider();
    var oldOptions = serviceProvider.GetRequiredService&lt;IOptions&lt;RazorViewEngineOptions&gt;&gt;().Value;
    services.AddViewLocationExpander(new ViewLocationExpander());
    serviceProvider = services.BuildServiceProvider();
    var newOptions = serviceProvider.GetRequiredService&lt;IOptions&lt;RazorViewEngineOptions&gt;&gt;().Value;

    // Assert
    Assert.True(newOptions.ViewLocationExpanders.Count &gt; oldOptions.ViewLocationExpanders.Count);
}


Questions


Am I going beyond the scope of what unit testing should include? I'm afraid that my code is actually testing the basic functions of generic collections and/or aspects of ASP.NET Core.
If my concern above is true, that should I write unit tests to this at all? How should it work?
I find your test is excelent (and I'll borrow it from you). I would, however, make it a litte bit more exact and not only test the counts of generated locations but also whether they have the expected values.

You are not testing basic functions of collections or ASP.NET-Core aspects because it doesn't matter how it's implemented. What you are testing is whether your application has all the view locations it needs to work correctly.

This is a very important (integration) test and you should not remove it but improve it by asserting the actual locations too. If this breaks then your app wont't work anymore so it's a real lifesaver.