.NET Core Manually Instantiating IOptions for Unit Testing

Posted by

One new feature of .NET Core is the built-in dependency injection container. Specifically, within the Configure Services method of the startup, you can easily configure options models. I like to leverage an AppSettings helper model to pass my settings around my application, but while doing so, I still need a way to easily break my dependencies for unit testing.

Background

To achieve the set up of having an AppSettings model being passed around the application, you need to create the app settings in your actual appsettings.json, have it match the model, and configure it within the start up. After doing so, you can pass in an IOptions<T> to a class and it will resolve correctly.

In appsettings.json:

{
    "AppSettings": {
        "ApplicationName": "My Test App",
        "DefaultTimeout": 60
    }
}

The AppSettings class:

public class AppSettings
{
    public string ApplicationName { get; set; }
    public int DefaultTimeout { get; set; }
}

In Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
}

Now, usage is as follows:

public class ValuesController
{
    public ValuesController(IOptions<AppSettings> appSettingsOptions)
    {
        var appSettings = appSettingsOptions.Value;
        //appSettings.ApplicationName = "My Test App"
        //appSettings.DefaultTimeout = 60

    }
}

Unit Testing

Now we get to the real problem. I don’t have a dependency injection container strictly for my unit testing, so I can’t instantiate a ValuesController that is using the IOptions<AppSettings>. I could try to set one up, but that’s definitely overkill for just being able to use some settings. Luckily, there is a way to manually create an instance of an IOptions<T>, using the Options.Create() method.

So, building up my dependency looks like this:

var settings = new AppSettings(){
    ApplicationName = "Test Project",
    DefaultTimeout = 15
};
IOptions<AppSettings> appSettingsOptions = Options.Create(settings);

var valuesController = new ValuesController(appSettingsOptions);
//Actually test ValuesController here

I originally encountered this issue while attempting to leverage a service that was using IOptions from within a .NET Core AWS Lambda function that was going through a direct function. In that scenario I needed a way to manually instantiate that IOptions model just like for unit testing. Thanks to being able to create an IOptions with Options.Create(), both of those use cases are not a problem.

9 comments

    1. Yeah definitely, and if that’s what you prefer to do, there’s nothing wrong with that. This way doesn’t require adding a dependency to FakeItEasy though.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.