Test IOptionsMonitor<T> in ASP.NET Core
Tags: aspnetcore, dotnet, csharp
Published: 2019-11-23 01:01:47

---
title: Test IOptionsMonitor<T> in ASP.NET Core
published: true
description: How to test options pattern in ASP.NET Core (IOptionsMonitor<T>)
tags: #aspnetcore #dotnet #csharp
---
***
*Welcome!* Spanish articles on [LinkedIn](https://www.linkedin.com/in/mpetrinidev/). You can follow me on [Twitter](https://twitter.com/mpetrinidev/) for news.
***

Imagine you are using the options pattern in .NET Core to set up some configuration in your application, and you need to test it. Through this example, you will learn how to test the options you have configured.

# Let's begin

## Option Class

An options class must be non-abstract with a public parameterless constructor. I create a class called `GmailSmtpOptions` to simulate the configuration that we need for a Gmail email service.

```cs
    public class GmailSmtpOptions
    {
        public string Server { get; set; }
        public bool UseAuthentication { get; set; }
        public bool UseSecureConnection { get; set; }
        public string Username { get; set; }
        public string Password { get; set; }
        public int Port { get; set; }    
    }
```

## Service collection extension

I create a simple service collection extension to add `GmailSmtpOptions` to the container.

I'm configuring the options passing a delegate in the `AddCustomOptions` and use the `Configure` method of the container.

```cs
    public static class ServiceCollectionExtensions
    {
        public static IServiceCollection AddCustomOptions(this IServiceCollection serviceCollection, Action<GmailSmtpOptions> gmailSmtpOptions)
        {
            serviceCollection.Configure(gmailSmtpOptions);
            return serviceCollection;
        }
    }
```

## xUnit class for test

### Arrange

I set up the test with some information about the SMTP server. Also, I use the service collection to call the `AddCustomOptions` extension method that we previously created.

```cs
    var server = "smtp.gmail.com";
    var useAuth = true;
    var useSecCon = true;
    var username = "username";
    var password = "password";
    var port = 465;

    var serviceCollection = new ServiceCollection();
    serviceCollection.AddCustomOptions(gmail =>
    {
        gmail.Server = server;
        gmail.UseAuthentication = useAuth;
        gmail.UseSecureConnection = useSecCon;
        gmail.Username = username;
        gmail.Password = password;
        gmail.Port = port;
    });
```

### Act

Then, I call the `BuildServiceProvider` method to create the provider containing services from the provided `IServiceCollection`  and get the `IOptionsMonitor<T>` service.

```cs 
    var builder = serviceCollection.BuildServiceProvider();
    var optionsMonitor = builder.GetService<IOptionsMonitor<GmailSmtpOptions>>();
```
### Assert 

We get the IOptionsMonitor<GmailSmtpOptions>, and now we need to compare the values configured previously. We use the `CurrentValue` property to get the current `TOptions` instance (GmailSmtpOptions).

```cs
    //Assert 1
    optionsMonitor.Should().NotBeNull();
    optionsMonitor.CurrentValue.Should().NotBeNull().And.BeOfType<GmailSmtpOptions>();
    
    var gmailOptions = optionsMonitor.CurrentValue;

    //Assert 2
    gmailOptions.Should().NotBeNull();
    
    //Assert 3
    gmailOptions.Server.Should().NotBeNullOrEmpty().And.Be(server);
    gmailOptions.UseAuthentication.Should().Be(useAuth);
    gmailOptions.UseSecureConnection.Should().Be(useSecCon);
    gmailOptions.Username.Should().NotBeNullOrEmpty().And.Be(username);
    gmailOptions.Password.Should().NotBeNullOrEmpty().And.Be(password);
    gmailOptions.Port.Should().Be(port);
```

That's all! 


### Complete code

```cs
    public class ServiceCollectionExtensionsTest
    {
        [Fact]
        public void AddCustomOptions_NoConfigureOptions_ConfigureOptionsOk()
        {
            //Arrange
            var server = "smtp.gmail.com";
            var useAuth = true;
            var useSecCon = true;
            var username = "username";
            var password = "password";
            var port = 465;
            
            var serviceCollection = new ServiceCollection();
            serviceCollection.AddCustomOptions(gmail =>
            {
                gmail.Server = server;
                gmail.UseAuthentication = useAuth;
                gmail.UseSecureConnection = useSecCon;
                gmail.Username = username;
                gmail.Password = password;
                gmail.Port = port;
            });
            
            //Act
            var builder = serviceCollection.BuildServiceProvider();
            var optionsMonitor = builder.GetService<IOptionsMonitor<GmailSmtpOptions>>();

            //Assert 1
            optionsMonitor.Should().NotBeNull();
            optionsMonitor.CurrentValue.Should().NotBeNull().And.BeOfType<GmailSmtpOptions>();
            
            var gmailOptions = optionsMonitor.CurrentValue;

            //Assert 2
            gmailOptions.Should().NotBeNull();
            
            //Assert 3
            gmailOptions.Server.Should().NotBeNullOrEmpty().And.Be(server);
            gmailOptions.UseAuthentication.Should().Be(useAuth);
            gmailOptions.UseSecureConnection.Should().Be(useSecCon);
            gmailOptions.Username.Should().NotBeNullOrEmpty().And.Be(username);
            gmailOptions.Password.Should().NotBeNullOrEmpty().And.Be(password);
            gmailOptions.Port.Should().Be(port);
        }
    }
```

I'm using the following packages in the test project.

```
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
    <PackageReference Include="xunit" Version="2.4.0" />
    <PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
    <PackageReference Include="coverlet.collector" Version="1.0.1" />
```