Test IOptionsMonitor<T> in ASP.NET Core
Mauro Petrini 👨💻
Posted on November 23, 2019
Welcome! Spanish articles on LinkedIn. You can follow me on Twitter 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.
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.
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.
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.
var builder = serviceCollection.BuildServiceProvider();
var optionsMonitor = builder.GetService<IOptionsMonitor<GmailSmtpOptions>>();
Assert
We get the IOptionsMonitor, and now we need to compare the values configured previously. We use the CurrentValue
property to get the current TOptions
instance (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);
That's all!
Complete code
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" />
Posted on November 23, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.